包装的重要性

我记得大约15年前开始学习Java的时候。 我读了很多有关“包装”和“命名空间”的东西,但我完全不了解。 可悲的是:虽然包装的某些方面几乎为业内每个人所了解,但其他方面却并非如此。 因此,让我们看一下哪些软件包最适合。

命名空间:

通过为您的所有程序包加上您所控制的域的前缀,可以确保您的类名是唯一的。 这对于数量惊人的开源项目的成功至关重要。 每个项目都可以(并且可能在某个阶段做一个)定义一个“ Filter”类,而不会干扰该类的所有其他同名类(可怜的开发人员除了从网络上复制了一些没有导入语句的代码外,现在有了以确定实际引用了哪个Filter类)。 这是一个很好的理解,而且我还没有看到根软件包的任何相关用法。

组织:

我儿子有一大盒乐高积木。 可能有成千上万个。 当他寻找简单的2×4砖块时,这不是问题。 但是,当他正在搜索仅在集合中存在4次甚至只有一次的特殊砖块时? 可能需要很长时间才能找到它。 将其与药剂师柜子比较。 数百种药物,通常只需几秒钟即可找到合适的药物。 而且他们甚至都没有使用Google! 它们只是每种药物所属的严格订购原则,包括一条规则,即如何确定新药的正确框。 由于涉及的每个人都知道该原理,因此很容易确定要在其中找到毒品的正确盒子。 当在项目早期建立时,这种排序原则将非常有用。
在定义这样的原则时,一个标准在大多数时间是不够的。 但是,如果您使用更多的规则,则使规则正交,以确保它们不会干扰。 这意味着没有规则说:“所有数据库访问代码都必须放在软件包x中”,而另一条规则规定“与客户相关的所有代码都必须放入软件包y中”。 否则,您将不知道将CustomerDAO放在哪里。 而是在包树的不同深度上应用正交规则。 我的默认包结构如下所示:

<organisational-prefix>.<application>.<deployment-unit>.<module>.<layer>.<optional further substructure if needed>

这将导致软件包名称,例如com.mycompany.theCoolApp.server.user.persistencecom.mycompany.theCoolApp.client.shoppingCart.presentation

如果您查看这样的包结构,则很明显新类属于什么地方,或者类似的东西已经存在的地方。 如果避免使用诸如utilmisc类的名称,它们可能会或多或少隐藏所有内容,则效果会更好。 您也可以查看这些软件包,并立即了解有关体系结构的知识。 一旦您看到一个名为clientwebserverbatchserver的软件包级别,您就会在脑海中形成一个模型,说明应用程序的结构以及名称的选择是否正确。 由于在每个module中都应用了相同的layers规则,因此您也可以在较低的软件包中找到有关应用程序结构的更多信息。

之间的module传达应用程序要处理的领域的类型。 很自然,重要的概念会得到自己的包装,从而使每个检查代码的人都可以声明:这是此应用程序中的重要概念。

我还喜欢添加规则“A包必须包含a - b类,但不得包含c以上”与A,B和C的适当的值。 随着应用程序的增长,这将迫使创建新的程序包,从而使每个程序包保持可管理的大小。

当然,在较小的应用程序中,结构可能会缩小。 例如,如果只有一个部署单元,则无需为该分类使用单独的程序包级别。

包的最后一种用法是最被忽略的: 中间建模块 :Joe Average Developer主要关注类和方法以及单行代码,同时尝试在该级别上提出适合应用程序需求的代码结构。 通常,有些架构师会弄清楚如何部署应用程序,从而确定必要的部署单元(请考虑单独的jar)。 如果您看一下这些工件的规模,可能会发现一些有趣的东西:

  • 1种方法由大约10行代码组成。
  • 1类包括大约10种方法。
  • 1罐子大约包含100 – 1000类。

如果没有人照顾软件包,则至少会缺少一种结构,经常会缺少两层结构! 可以并且应该用包装来填补这个空白。 这不仅意味着包装应存在且尺寸合理,还意味着它们应遵循通用的设计准则。 特别是“ 单一责任原则”和对依赖项的正确处理:

单一责任原则:

利用上面提出的命名方案,完成了许多兑现SRP的工作。 如果软件包的内容符合其名称说明,那么在此方面一切都很好。

依赖性管理:

是更强悍的野兽。 Java当前没有提供适当的系统来控制软件包之间的依赖关系,尤其是超级软件包,即包含多个其他软件包的软件包。 有OSGI ,但是我发现使用它很麻烦 ,特别是因为我不需要所有的动态加载内容,但是会遭受类加载器问题的困扰。 也有拼图,但还不存在。 因此,我更喜欢使用本地测试来定义和验证所使用的应用程序的程序包结构。 我选择的工具是JDepend 。 它提供了程序包之间的依赖关系列表,您可以使用它们将它们与定义的规则进行比较。 有人创建了从程序包A到程序包B的依赖关系,该依赖关系不应该存在? 动臂,测试变成红色。
那么对包依赖项有用的规则是什么? 第一:无周期。 不在包级别上,也不在layer级别上或module级别上,如上所述。 第二:模块和层具有严格的顺序,在顺序上它们可以相互依赖,其他所有内容均被禁止。

这些规则极大地限制了开发人员的自由度。 但是以我的经验,它消除了违反“单一责任原则”的情况,该原则经常以循环依赖的形式出现。 例如,如果您有一个“订单”模块和一个“客户”模块,则感觉这两个需要彼此了解。 如果您有订单,则想知道该订单所属的客户。 如果您有客户,则必须能够告诉她所下的订单。 对? 应该是。 但是,您是否需要两侧都有完整的对象和功能? 可能不是。 例如,通过提供一个接口程序包,其中仅包含订购模块所需的客户功能的最核心部分,以及一个单独的完整的具有参考订单的客户模块, 可以打破这些依赖关系并在您的需求中实现更强的关注分离包装结构。

当您尝试开发应用程序时,这反过来会有所帮助。 今天的软件包有一天可能会成长为一个部署单元,如果您在部署单元之间存在循环依赖关系,则会遇到一些严重的问题。 也许您的团队成长为多个团队。 有了如上所述的干净的程序包结构,当团队必须坐在一起讨论由多个团队使用的程序包的更改时,您将有明显的界限可以拆分,并且还有明显的标准。

参考:来自Schauderhaft博客的JCG合作伙伴 Jens Schauder 的软件包重要性 。

翻译自: https://www.javacodegeeks.com/2013/01/the-importance-of-packages-3.html

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

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

相关文章

我的python学习笔记全集_我的python学习笔记

(此文是在实际工程中遇到的一些小问题&#xff0c;给予解决和整理。解决方法大多来自网上零散的文章。)1——如下代码&#xff0c;a[1,2,3]bab也是[1,2,3]了&#xff0c;接着a[0]4a[1]5a[2]6此时a变成[4,5,6]了&#xff0c;再看b&#xff0c;a变了之后没有对b进行新的引用&…

课时28.假链接(掌握)

什么是假链接&#xff1f; 就是点击之后不会跳转的链接我们称之为假链接。 假链接存在的意义&#xff1f; 在企业开发前期&#xff0c;其他界面都没有写出来&#xff0c;那么&#xff0c;我们就不知道应该跳转到什么地方&#xff0c;所以就只能使用假链接来代替&#xff0c;…

笔记45 | 代码性能优化建议[转]

地址 笔记45 | 代码性能优化建议[转] 目录 前言避免创建不必要的对象选择Static而不是Virtual常量声明为Static Final避免内部的Getters/Setters使用增强的For循环使用包级访问而不是内部类的私有访问避免使用float类型使用库函数谨慎使用native函数关于性能的误区前言 通常来说…

导弹拦截

链接 分析&#xff1a;经典DP题&#xff0c;最长不下降子序列的变种&#xff0c;同时需要记录路径&#xff0c;用pre[]数组记录当前结点的前一个结点的方法很妙 1 #include "iostream"2 #include "cstdio"3 #include "cstring"4 #include "…

JUnit4参数化和理论示例

我始终依靠TestNG将参数传递给测试方法&#xff0c;以便为我的测试或套件提供一些灵活性。 但是&#xff0c;使用JUnit4可以实现相同的灵活性。 要使用它很简单&#xff1a; package com.marco.test;import java.util.Arrays;import java.util.Collection;import junit.fram…

杨杰matlab神经网络30例,MATLAB神经网络30例

实例1 BP神经网络在非线性函数拟合中的应用11.1 理论基础11.1.1 BP网络概述11.1.2 BP神经网络的MATLAB函数21.2 非线性函数拟合方法6实例2 主元BP神经网络在股票价格预测中的应用122.1 理论基础122.1.1 主成分分析的原理122.1.2 主元神经网络与股票预测142.2 股票价格的预测方法…

HTMLCSS 问题

1.子div使用浮动&#xff0c;父div高度自适应(个人感觉好用) 方法&#xff1a; css: <style> .clear{ clear:both} </style> html&#xff1a;在父div关闭之前添加<div class"clear"></div> 本文转载于:猿2048⇛https://www.mk2048.com/…

python matplotlib数据可视化教程_matplotlib的Python数据可视化和探索——入门指南

matplotlib——最受欢迎的Python库&#xff0c;用于数据可视化和探索我喜欢在Python中使用matplotlib。这是我学会掌握的第一个可视化库&#xff0c;此后一直存在。matplotlib是最受欢迎的用于数据可视化和探索的Python库&#xff0c;这是有原因的——它提供的灵活性和敏捷性是…

mysql 查询所有子节点的相关数据

定义一个函数 CREATE DEFINERrootlocalhost FUNCTION getColumnChildLst(rootId INT) RETURNS varchar(1000) CHARSET utf8 BEGINDECLARE sTemp VARCHAR(1000);DECLARE sTempChd VARCHAR(1000);SET sTemp $;SET sTempChd cast(rootId as CHAR);WHILE sTempChd is not null DOS…

怎么用PHP实现年月日date,PHP date函数用法,php年月日写法

日期和时间信息在 PHP 内部是以 64 位数字存储的&#xff0c; 它可以覆盖当前时间前后 2920 亿年的时间&#xff0c;这个范围之广&#xff0c;足以满足现有应用的实际需求。需要注意的是&#xff0c; 这些PHP时间函数都是依赖服务器的区域设置的&#xff0c; 所以在使用它们的时…

python气象卫星云图解析_【我教你系列】想要实时的地球图像作为桌面?

Python 定时获取卫星图像做为桌面背景简介这两天看新闻的时候&#xff0c;突然发现最近有个台风产生&#xff0c;并且在不断的增强中。幸运的是从中央气象台预报的路径来看&#xff0c;不会登陆我国。也正是通过这则新闻&#xff0c;我发现了一个不错的卫星云图网站。(ps:这篇文…

CSS权重的比较方法

CSS的权重如下&#xff1a; !important Infinity正无穷 行间样式 1000 id 100 class|属性|唯类 10 标签|伪元素 1 通配符 0 256进制 当出现多个选择器时 在同一行的选择器权重相加即可 当两个混合选择器权重相同时优先选择后面的选择器 如&#xff1a; html <…

python_day8 面向对象常用 补充

__str__ 作用本来 打印 类对象是 打印的内存地址 但是在类中 增加 __str__ 参数 以后 再打印这个 类对象 就是显示 __str__中的 return __del__作用 当 实例化的对象 在内存中 被释放的时候执行 item操作通过 set get del 操作 item最终目的是将 类里面的 变量 像 字典一样操作…

Spring中的@Cacheable开销

Spring 3.1引入了很棒的缓存抽象层 。 最后&#xff0c;我们可以放弃所有本地化的方面&#xff0c;装饰器和污染我们与缓存相关的业务逻辑的代码。 从那时起&#xff0c;我们可以简单地注释重量级方法&#xff0c;并让Spring和AOP机械完成工作&#xff1a; Cacheable("bo…

电工接线模拟仿真软件_VERICUT数控加工仿真软件,最强的数控加工模拟软件,你知道么?...

VERICUT数控加工仿真软件,最强的数控加工模拟软件VERICUT软件及功能简介1、VERICUT软件简介VERICUT是美国CGTech公司开发一款专业的数控加工仿真软件&#xff0c;是当前全球数控加工程序验证、机床模拟、工艺程序优化软件领域的领导者。该软件自1988年开始推向市场以来&#xf…

php数据库创建文件失败怎么回事,安装zblogPHP提示“创建c_option.php失败”解决方法...

有zblog用户反应在安装zblog的最后一步时提示“创建c_option.php失败”&#xff0c;如下图&#xff1a;本文来说明下这个问题的原因和解决办法。问题产生的原因&#xff1a;c_option.php是zblog的数据库配置文件&#xff0c;当安装完成的时候程序会自动创建这个文件。如果你的主…

一次搞清楚Mysql联合索引,以及联合索引究竟用了多少

一群DBA朋友聊天&#xff0c;突然抛出一个某公司联合索引的面试题&#xff0c;当时好多人都蒙了&#xff0c;这次针对这个问题&#xff0c;做了个简单的实验&#xff0c;把联合索引的作用一次搞清楚 问题大概是这样的&#xff0c;联合索引&#xff08;a,b,c,d&#xff09;下面这…

CSS Variables

CSS原生变量(CSS自定义属性) 示例地址&#xff1a;https://github.com/ccyinghua/Css-Variables 一、css原生变量的基础用法 变量声明使用两根连词线"--"表示变量&#xff0c;"$color"是属于Sass的语法&#xff0c;"color"是属于Less的语法&a…

【基础中的基础】引用类型和值类型,以及引用传递和值传递

一直在博客园怼人&#xff0c;非常惭愧。所以郑重决定&#xff1a; 好好写一篇干货&#xff0c;然后再接着怼人。 这是一起帮上陈百万同学的求助&#xff0c;讲了一会之后&#xff0c;我觉得很有些普世价值&#xff0c;干脆就发到园子来。面向小白&#xff0c;高手轻拍。 我们从…

Java 7:使用NIO.2进行文件过滤–第3部分

大家好。 这是使用NIO.2系列进行文件过滤的第3部分。 对于那些尚未阅读第1 部分或第2部分的人 &#xff0c;这里有个回顾。 NIO.2是自Java 7起JDK中包含的用于I / O操作的新API。使用此新API&#xff0c;您可以执行与java.io相同的操作&#xff0c;以及许多出色的功能&#xf…