Netty的结构

位置:首页>文章>详情   分类: Java教程 > 编程技术   阅读(222)   2023-09-06 14:19:57

Netty 的包结构很棒。

每个程序员都应该学习它;每个系统都应该模仿它;每个项目经理都应该把它打印出来,拍在墙上,然后对开发人员说,“那个。”

Netty 是一个“……一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端”,但这在这里并不重要,因为我们没有分析它的行为。相反,请看图 1。

图 1:Netty 的包结构在 7 年内不断发展。

图 1 显示了 Netty 不断发展的包结构的 spoiklin 图(圆圈是包;直线是页面下的依赖关系;曲线是页面上的依赖关系),如果您不能立即看出它的结构有多好是,然后看看 JunitStrutsAnt

也不仅仅是“旁观者眼中有好的结构”。 结构混乱提供了一个程序结构糟糕程度的客观衡量标准:结构混乱程度越低,结构越好。 Netty 的混乱程度远低于几乎所有其他情况,请参见表 1。

程序 包结构紊乱
蚂蚁 81%
联合 76%
Struts 74%
Lucene 73%
健身 61%
Spring 35%
网络 26%

表 1:本系列中审查的所有项目的结构紊乱。

更重要的是,图 2 显示了这种最终的结构紊乱并非偶然。 Netty 的结构紊乱在其七年的生命周期中一直很低。

图 2:Netty 在 11 个版本中的结构混乱(与其他版本进行比较)。

那么:为什么这个包结构这么好?

给定如图 1 所示的图表,我们可以提出两个快速问题来评估(粗略地)所描述结构的优点。

在商业软件开发中,“良好的结构”简单意味着“更新便宜”。此外,证据 建议每个了解连锁反应的程序员都知道:X 依赖的东西越多,受到影响的可能性就越大通过连锁反应,因此 X 的成本可能更高。

因此,选择一个严重依赖于其他包的包并询问(A)我们能否轻松识别依赖的包以及(B)这些依赖包的整体子集有多大?

结构不良的程序会掩盖这些依赖关系,而仔细检查通常会揭示对几乎整个系统的依赖关系。然而,结构良好的程序清楚地显示了所依赖的包,而且它们很少。

让我们首先针对结构不良的程序提出这两个问题。

图 3 显示了 Jenkins 可怕的 90% 的结构混乱,然后显示了五个包(工具提示)中最依赖于其他包的突出显示的传递依赖性。

图 3:詹金斯,哦詹金斯。

清楚地跟踪 Jenkins 中的依赖关系……是一个挑战,许多包依赖于系统其余部分的 75% 以上。

图 4 重复了该实验,但显示了五个最依赖于其他包的 Netty 包的传递依赖性:epoll、spdy、websocketx、httpnio

图 4:突出显示(蓝色)Netty 中最差的传递依赖。

与Jenkins形成鲜明对比的是,我们可以看到依赖的Netty包是多么的少。 Netty 有 55 个包,但任何其他包所依赖的最多只有 12 个,也就是系统的 22%。

Netty 的包结构是否完美?当然不是。特别是 internalconcurrent 之间的循环依赖在核心 internal/concurrent/channel/buffer/util 包集群中产生了令人遗憾的强耦合。

从表面看,Netty 的类结构确实很糟糕。 Netty 的设计者在构建其类级 时显然放弃了一些优秀的结构原则。丢人现眼。

但是看看那个包结构……哇。

最后,不是分析 Netty 的关键版本,而是架构观察本身。 Netty 的架构师似乎已经决定了一个相当出色的部署策略。下载 Netty 不仅可以为您提供一个一体化的 jar 文件,还可以为您提供 13 个包含系统独立部分的 jar 文件。大概您可以加载所有 Netty 或只加载您想要的部分。

一个 jar 文件,“通用”jar,包含 internal/concurrent/channel/buffer/util 包集群,而其他文件包含,例如,“codec”、“tcnactive”、“transport”、等等,这表明后面这些 jar 是公共 jar 的客户端,但不是彼此的客户端,因此彼此之间没有依赖关系。因此,在他们的部署中,Netty 的设计者可能已经将他们的子系统的分离和封装奉为神明,这导致了这种行业领先的包结构。

剩下的唯一问题是:为什么没有更多项目效仿 Netty?为什么 Jenkins 有 90% 的结构紊乱?为什么 Jenkins 的设计者没有正确地划分他们的系统以减少包间耦合?为什么软件开发领域如此愿意接受这些糟糕的结构所产生的成本?

我们不是比这更好吗?

概括

如果每年颁发一次当今使用的最佳 Java 包结构的奖项,Netty 将连续七年获奖。

标签2: Java教程
地址:https://www.cundage.com/article/jcg-the-structure-of-netty.html

相关阅读

Java HashSet 教程展示了如何使用 Java HashSet 集合。 Java哈希集 HashSet 是一个不包含重复元素的集合。此类为基本操作(添加、删除、包含和大小)提供恒定时间性...
SpringApplicationBuilder 教程展示了如何使用 SpringApplicationBuilder 创建一个简单的 Spring Boot 应用程序。 春天 是用于创建企业应...
通道是继 buffers 之后 java.nio 的第二个主要新增内容,我们在之前的教程中已经详细了解了这一点。通道提供与 I/O 服务的直接连接。 通道是一种在字节缓冲区和通道另一端的实体(通...
课程大纲 Elasticsearch 是一个基于 Lucene 的搜索引擎。它提供了一个分布式的、支持多租户的全文搜索引擎,带有 HTTP Web 界面和无模式的 JSON 文档。 Elasti...
解析器是强大的工具,使用 ANTLR 可以编写可用于多种不同语言的各种解析器。 在这个完整的教程中,我们将: 解释基础:什么是解析器,它可以用来做什么 查看如何设置 ANTLR 以便在 Java...
Java 是用于开发各种桌面应用程序、Web 应用程序和移动应用程序的最流行的编程语言之一。以下文章将帮助您快速熟悉 Java 语言,并迈向 API 和云开发等更复杂的概念。 1. Java语言...
Java中的继承是指子类继承或获取父类的所有非私有属性和行为的能力。继承是面向对象编程的四大支柱之一,用于提高层次结构中类之间的代码可重用性。 在本教程中,我们将了解 Java 支持的继承类型,...
Java Message Service 是一种支持正式通信的 API,称为 网络上计算机之间的消息传递。 JMS 为支持 Java 程序的标准消息协议和消息服务提供了一个通用接口。 JMS 提...
Java 项目中的一项常见任务是将日期格式化或解析为字符串,反之亦然。解析日期意味着你有一个代表日期的字符串,例如“2017-08-3”,你想把它转换成一个代表 Java 中日期的对象,例如Ja...
之前,我介绍了spring 3 + hibernate 集成 示例和struts 2 hello world 示例。在本教程中,我将讨论在将 spring 框架与 struts 与 hibern...