使用Degraph管理软件包依赖关系

软件开发领域的很大一部分是使系统的复杂性尽可能地低。 但是复杂性到底是什么? 虽然确切的语义有很大不同,但取决于您询问的人,大多数人可能都认为这与系统中部件的数量及其交互有很大关系。

考虑太空中的大理石,即行星,月亮或恒星。 没有任何交互,这就像系统可能会变得无聊。 什么都没发生。 如果大理石移动,它会以完全相同的方式移动。 老实说,甚至没有办法确定它是否在移动。 笨蛋。

在系统中添加第二块大理石,让它们彼此吸引,就像地球和月亮一样。 现在,该系统更加有趣。 如果它们不太快,则这两个对象会彼此绕圈。 有点有趣。

现在添加第三个对象。 在一般情况下,事情变得如此有趣,以至于我们甚至无法预测会发生什么。 整个系统不仅变得复杂,而且变得混乱。 您现在有一个三体问题 。在一般情况下,此问题无法解决,即我们无法预测系统会发生什么。 但是有一些特殊情况。 尤其是其中两个对象彼此非常接近的情况(例如地球和月亮),而第三个对象相距太远,以至于两个第一个对象的行为就像一个对象。 在这种情况下,您可以用两个粒子系统来近似该系统。

但是,这与Java有什么关系? 这听起来更像物理学。

我认为软件开发在某些方面是相似的。 完整的应用程序是从整体上变得复杂的方式。 为了克服这种复杂性,我们将系统分为可以自己理解的部分(类),并隐藏了它们的内部复杂性,这样,当我们查看较大的图片时,不必担心代码中的每个代码行类,但仅将类作为一个实体。 实际上,这与物理学家对系统所做的非常相似。

但是,让我们看一下事物的规模。 软件的基本构建块是代码行。 为了控制复杂性,我们将在方法中一起工作的代码行捆绑在一起。 单个方法中有多少行代码会有所不同,但大约为10行代码。

接下来,将方法收集到类中。 一个类中有多少种方法? 通常按10种方法排序!

然后? 我们将100-10000个班级捆绑在一个罐中! 我希望我不是唯一认为某事不对劲的人。

我不确定从Jigsaw项目中会得到什么,但是目前Java仅提供软件包来捆绑类。 包并不是一个强大的抽象,但是它是我们唯一的抽象,因此我们最好使用它。

大多数团队确实使用软件包,但不是以非常结构化但临时的方式使用软件包。 结果类似于试图将月亮和太阳视为系统的一部分,而将地球视为另一部分。 结果可能有效,但可能与托勒密的行星模型一样直观。 取而代之的是,根据标准确定如何区分包装。 我个人称它们为切片,是受Oliver Gierke的一篇文章的启发。 按重要性顺序排列的可能切片为:

  • 该类最终应位于的可部署jar文件
  • 类所属的用例/功能/业务模型的一部分
  • 类所属的技术层

结果生成的软件包将如下所示:<domain>。<deployable>。<domain part>。<layer>

决定去哪儿上课应该很容易。 并且即使您不使用技术层分隔,它也应将包装保持在合理的尺寸。

但是,您从中得到什么呢? 找到类比较容易,但是仅此而已。 您还需要一个规则来使它真正值得: 不得有循环依赖项!

这意味着,如果包A中的类引用了包B中的类,则B中的任何类都不能引用A。如果引用是通过多个其他包间接引用的,则这也适用。 但这还不够。 切片也应该是无周期的,因此,如果域部分X引用了其他域部分Y,则反向依赖性一定不存在!

实际上,这将对您的程序包和依赖项结构设置一些相当严格的规则。 这样做的好处是,它变得非常灵活。

没有这样的结构,将您的项目分成多个部分可能会很困难。 是否曾经尝试过在另一个应用程序中重用应用程序的一部分,只是为了意识到您必须包含大部分应用程序才能进行编译? 是否曾经尝试将应用程序的不同部分部署到不同的服务器,只是为了意识到自己做不到? 在使用上述方法之前,这肯定发生在我身上。 但是,通过这种更严格的结构,您可能想重用的部分将几乎完全依赖于依赖链的末端,因此您可以将它们打包并捆绑在自己的jar中,或者只是将代码复制到不同的容器中项目并在很短的时间内进行编译。

同样,在尝试保持软件包和分片周期自由的同时,您将不得不认真思考,每个涉及的软件包实际上都是关于什么的。 在许多情况下,这些可以极大地改善我的代码库。

因此,剩下一个问题:依赖关系很难看到。 没有工具,很难保持代码库的自由。 当然,有很多工具可以检查周期,但是清理这些周期很困难,而且大多数工具提供这些周期的方式也无济于事。 我认为一个需求是两件事:

  1. 一个简单的测试,可以与所有其他测试一起运行,并且在创建依赖项圈时失败。
  2. 可视化类之间所有依赖关系的工具,同时显示每个类所属的切片。

惊喜! 我可以推荐一个很棒的工具: Degraph ! (我是作者,所以我可能会有偏见)

您可以像这样在JUnit中编写测试:

assertThat(
classpath().including("de.schauderhaft.**")
.printTo("degraphTestResult.graphml")
.withSlicing("module", "de.schauderhaft.(*).*.**")
.withSlicing("layer", "de.schauderhaft.*.(*).**"),
is(violationFree())
);

该测试将分析类路径中以de.schauderhaft开头的所有内容。 它将以两种方式对类进行切片:通过获取包名称的第三部分和通过获取包名称的第四部分。 因此,类名de.schauderhaft.customer.persistence.HibernateCustomerRepository最终出现在模块客户和层持久性中。 并且它将确保模块,层和包是无周期的。

并且,如果找到依赖项圆,它将创建一个graphml文件,您可以使用免费的图形编辑器yed打开该文件 。 通过一点布局,您将得到如下所示的结果,其中导致循环依赖关系的依赖关系被标记为红色。

unit

同样,有关如何实现良好的可用布局的更多详细信息,我必须参考Degraph的文档 。

另请注意,图表主要以绿色为主,并带有少许红色,非常适合本季节!

翻译自: https://www.javacodegeeks.com/2014/12/managing-package-dependencies-with-degraph.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转载] 应急管理体系及其业务流程研究

转载于:https://www.cnblogs.com/6DAN_HUST/archive/2013/03/04/2942337.html

WP8手机上的图标

一直不清楚WP8手机上两个圆的标志是什么意思&#xff0c;今天看到下面的链接&#xff0c;终于搞明白了&#xff0c;原来是打开了GPS就有。 http://www.windowsphone.com/en-us/how-to/wp8/basics/what-do-the-icons-on-my-phone-mean 转载于:https://www.cnblogs.com/wonderow/…

ASIHTTPRequest类库简介和使用说明

官方网站&#xff1a; http://allseeing-i.com/ASIHTTPRequest/ 。可以从上面下载到最新源码&#xff0c;以及获取到相关的资料。 使用iOS SDK中的HTTP网络请求API&#xff0c;相当的复杂&#xff0c;调用很繁琐&#xff0c;ASIHTTPRequest就是一个对CFNetwork API进行了封装&a…

UltraESB的首选IDE – IntelliJ IDEA

在AdroitLogic&#xff0c;我们长期以来一直在使用IntelliJ IDEA进行开发。 它是Java和相关语言/技术的最佳IDE&#xff08;它可能也是许多其他语言的选择&#xff0c;但我的经验主要是Java和相关技术&#xff09;。 Groovy和IDEA的Grails的集成很棒。 通过自动发现JDBC驱动程…

跟我一步一步开发自己的Openfire插件

这篇是简单插件开发&#xff0c;下篇聊天记录插件。 开发环境&#xff1a; System&#xff1a;Windows WebBrowser&#xff1a;IE6、Firefox3 JavaEE Server&#xff1a;tomcat5.0.2.8、tomcat6 IDE&#xff1a;eclipse、MyEclipse 8开发依赖库&#xff1a; Jdk1.6、jasper-com…

Apache FOP与Eclipse和OSGi的集成

Apache FOP是由XSL格式化对象&#xff08; XSL-FO &#xff09;驱动的开源打印处理器。 例如&#xff0c;将数据对象转换为PDF可能非常有用。 但是&#xff0c;将其集成到PDE中并最终以OSGi Service的形式运行并最终显得有些麻烦。 因此&#xff0c;我提供了一个P2存储库&…

不删除侦听器–使用ListenerHandles

听一个可观察的实例并对它的变化做出反应很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。 总览 这篇文章将首先讨论这种情况&#xff0c;然后再讨论常见的方法和问题所在。 然后&#xff0c;它将提供解决大多数问题的简单抽象…

使用Google Guava Cache进行本地缓存

很多时候&#xff0c;我们将不得不从数据库或另一个Web服务获取数据或从文件系统加载数据。 在涉及网络呼叫的情况下&#xff0c;将存在固有的网络等待时间&#xff0c;网络带宽限制。 解决此问题的方法之一是在应用程序本地拥有一个缓存。 如果您的应用程序跨越多个节点&…

JAX-RS 2.0:服务器端处理管道

这篇文章的灵感来自JAX-RS 2.0规范文档 &#xff08;附录C&#xff09;中的Processing Pipeline部分。 我喜欢它是因为它提供了JAX-RS中所有模块的漂亮快照-以准备好吞咽的胶囊形式&#xff01; 礼貌– JAX-RS 2.0规范文档 因此&#xff0c;我想到了使用此图简要概述不同的JA…

基于TCP/IP的文件服务器编程一例

来源&#xff0c;华清远见嵌入式学院实验手册&#xff0c;代码来源&#xff1a;华清远见曾宏安 实现的功能&#xff1a; 编写TCP文件服务器和客户端。客户端可以上传和下载文件 客户端支持功能如下&#xff1a; 1.支持一下命令 help 显示客户端所有命令和说明 list 显示服务器…

【Linux系统基础】(2)在Linux上部署MySQL、RabbitMQ、ElasticSearch、Zookeeper、Kafka、NoSQL等各类软件

实战章节&#xff1a;在Linux上部署各类软件 前言 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;…

JDK 7和JDK 8中大行读取速度较慢的原因

我之前发布了博客文章“使用JDK 7和JDK 8读取慢速行”&#xff0c;并且在该问题上有一些有用的评论来描述该问题。 这篇文章提供了更多解释&#xff0c;说明为何该文章中演示的文件读取&#xff08;并由Ant的LineContainsRegExp使用 &#xff09;在Java 7和Java 8中比在Java 6中…

Spring Stateless State Security第3部分:JWT +社会认证

我的Stateless Spring Security系列文章的第三部分也是最后一部分是关于将基于JWT令牌的身份验证与spring-social-security混合在一起的。 这篇文章直接建立在此基础上&#xff0c;并且主要集中在已更改的部分上。 想法是使用基于OAuth 2的“使用Facebook登录”功能来替换基于用…

nyoj239 月老的难题 二分图 匈牙利算法

月老的难题 时间限制&#xff1a;1000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;4描述月老准备给n个女孩与n个男孩牵红线&#xff0c;成就一对对美好的姻缘。 现在&#xff0c;由于一些原因&#xff0c;部分男孩与女孩可能结成幸福的一家&#xff0c;部分可能不会结…

Web应用程序体系结构– Spring MVC – AngularJs堆栈

Spring MVC和AngularJs共同为构建表单密集型Web应用程序提供了一个真正高效且吸引人的前端开发堆栈。在这篇博客文章中&#xff0c;我们将看到如何使用这些技术构建表单密集型Web应用程序&#xff0c;并将这种方法与其他方法进行比较可用选项。 可以在此github 存储库中找到功能…

antd Datepicker组件报错 ——date.clone is not a function或者date1.isAfter is not a function

问题描述&#xff1a; antd Datepicker组件报错 ——date.clone is not a function或者date1.isAfter is not a function 原因分析&#xff1a; 在From中渲染默认值&#xff0c;一般数据请求拿到返回值存在异步&#xff0c;会晚于渲染&#xff0c;因此日期转换不能放在DatePi…

集成CDI和WebSockets

考虑尝试一个简单的Java EE 7原型应用程序&#xff0c;该应用程序涉及JAX-RS&#xff08;REST&#xff09;&#xff0c;WebSockets和CDI。 注意 &#xff1a;不想让它成为破坏者-但这篇文章主要讨论了我在尝试使用Web套接字和使用CDI作为“胶水”的REST&#xff08;在Java EE应…

Java中连接字符串的最佳方法

最近有人问我这个问题–在Java中使用运算符连接字符串是否对性能不利&#xff1f; 这让我开始思考Java中连接字符串的不同方法&#xff0c;以及它们如何相互对抗。 这些是我要研究的方法&#xff1a; 使用运算符 使用StringBuilder 使用StringBuffer 使用String.concat() …

十大最常见的Java性能问题

Java性能是所有Java应用程序开发人员都关心的问题&#xff0c;因为快速使应用程序与使其正常运行同等重要。 史蒂文海恩斯&#xff08;Steven Haines&#xff09;使用他在Java性能问题上的个人经验得出的结论是&#xff0c; 大多数问题都有共同的根本原因 。 因此&#xff0c;作…

Unity3D 访问Access数据库

Unity3D 访问Access数据库 在开始这个小教程之前呢&#xff0c;其实在网上你已经可以找到相关的资料了&#xff0c;但是我还是要把我自己做练习的一点东西分享出来。写这个教程的主要原因呢&#xff0c;是一个朋友在u3d的官网论坛里&#xff0c;找到了这个demo&#xff0c;但是…