如何使代码模块化?

时间:2009-09-18 12:20:44

标签: java module osgi modularity

我有一些Java程序,现在我想知道它是否是模块化的,如果它是模块化的,那么在多大程度上,因为模块化永远不能是二进制术语,即0或1。 我如何确定特定代码在很大程度上是模块化的。我想知道如何使代码更加模块化?

10 个答案:

答案 0 :(得分:37)

模块化的一些基准:

  1. 您执行特定任务的次数 rewriting similar code 多少次?
  2. 如果您在程序的某个部分更改某些内容, refactor your code 需要多少代码?
  3. 文件更小更容易导航?
  4. application modules是否在需要时充分独立地执行?
  5. 你的代码如何减少灾难性?当你只删除一个函数或变量时,一切都会失败吗? 重新命名一个类时会出现20多个错误吗?(对于Instance,您可以实现堆叠机制以跟踪应用程序中的所有跃点)
  6. 自然语言使用代码的接近程度(即模块及其子组件代表更多真实世界的对象,而不必过多关注网络源文件的大小)。
  7. 了解更多提示check this out以及software quality

    上的提示

    至于您对使您的代码更加模块化的关注首先,您应该问自己上述问题,获取具体答案,然后查看this

    基本理念是将您的应用程序分解为尽可能小的代码片段,整齐地排列在众多易于理解和可访问的目录布局中。

    应用中的每种方法都必须不超过所需处理的最小量化。将这些方法组合到越来越多的宏级别方法中应该会引导您回到应用程序

答案 1 :(得分:25)

关键点是

  • 关注点分离
  • 衔接
  • 封装(通过接口通信)
  • 可替代性
  • 复用性

此类模块系统的一个很好的例子是标准汽车零件,如磁盘制动器和汽车音响。 在制造汽车时,您不希望从头开始构建汽车音响。你宁愿买它并插上它。你也不希望制动系统影响汽车音响 - 或者更糟糕的汽车音响会影响制动系统。

要回答您的问题,“我如何确定特定代码在很大程度上是模块化的”,我们可以形成问题来测试模块性。 您是否可以轻松地用其他内容替换您的模块,而不会影响应用程序的其他部分?

XML解析器可能是另一个例子。一旦获得DOM接口,您实际上并不关心下面使用哪种XML解析器实现(例如Apache Xerces或JAXP)。

在Java中,另一个问题可能是:是否可以通过interface访问所有功能?接口几乎可以解决低耦合问题。

此外,您能用一句话描述系统中的每个模块吗?例如,汽车音响播放音乐和广播。盘式制动器使车辆安全减速。


(这是我写给What is component driven development?

的内容

根据维基百科,基于组件的开发是Component-based software engineering (CBSE)的别名。

  

[它]是软件的一个分支   工程,其优先级是   关注点分离   广泛的功能   在给定的软件中可用   系统

这有点模糊,所以让我们看看更多细节。

  

单个组件是一种软件   包,或模块,那   封装了一组相关的   功能(或数据)。

     

所有系统进程都放入   单独的组件,以便所有的   每个内部的数据和功能   组件在语义上是相关的   (就像内容一样   类)。由于这个原则,   通常说组件是   模块化内聚

所以,根据这个定义,一个组件可以是任何东西,只要它做的一件事情真的很好而且只有一件事。

  

关于全系统   协调,组件沟通   通过接口相互之间。 [...]   该原理产生称为封装的组件。

所以这听起来越来越像我们认为好的API或SOA应该是这样的。

提供的接口由棒棒糖表示,必需的接口由连接到UML组件外边缘的开放套接字符号表示。

alt text

  

另一个重要的属性   组件就是它们   可替代,这样一个组件   可以被另一个替换(at   设计时间或运行时间),如果   初始组件的要求   (通过接口表示)得到满足   由后继组成部分。

     

可重用性很重要   高品质的特点   软件组件。一个软件   组件应该设计和   实施,以便可以重复使用   在许多不同的计划中。

可替代性和可重用性是使组件成为组件的原因。 那么这与面向对象编程之间的区别是什么?

  

面向对象的想法   编程(OOP)就是那个软件   应该写一个   心理模型的实际或想象   它代表的对象。 [...]

     

基于组件的软件工程,   相比之下,没有这样的   假设,而是说明   软件应该通过粘合来开发   预制组件在一起很多   就像在电子领域或   力学。

答案 2 :(得分:3)

要回答您关于如何制作更具模块性的代码的具体问题,可采用以下几种方法:

  • 模块化的最佳工具之一是发现代码重用。如果您发现您的代码在多个位置执行相同的(或非常相似的)事物,则它是模块化的良好候选者。

  • 确定哪些逻辑片段可以独立,在某种意义上,其他逻辑将使用它们而不需要知道它们是如何构建的。这有点类似于OO设计中的内容,尽管模块/组件不一定需要与OO中的建模对象相对应。

答案 3 :(得分:2)

HeJ小鼠,

请参阅“如何封装软件(第1部分)”,此处:

http://www.edmundkirwan.com/encap/overview/paper7.html

此致

答案 4 :(得分:1)

由于这已被'osgi'标记,我可以提出与OSGi相关的观点。

简短的回答是,可以从完全意大利面条代码到模块化的小步骤;它不一定是大爆炸。例如,即使意大利面条代码依赖于某种bolognaise日志库,所以在某种意义上,它已经是模块化的,只有一个非常大的Metball(抱歉,模块)。

诀窍是将大肉丸打成一个较小的块,然后是一个稍微不那么大的肉丸然后递归。它并非都必须一气呵成;每次只需更多地切断,直到没有任何东西可以移除。

对于OSGi来说,仍然可以将一个超级jar放入一个包中。实际上,你可以在不改变位的情况下做到这一点;或者通过修改Manifest.MF,或者将其包装在另一个JAR中并在清单中指定Bundle-ClassPath:metaball.jar。

如果不这样,像BND这样的工具可以帮助您生成所需的正确数据,然后可以轻松地将其放入OSGi运行时。但是要注意过度耦合的代码,以及那些与类加载器混在一起的东西 - 那些会让你失望。

答案 5 :(得分:0)

假设我理解你的问题,你想知道什么使代码模块化,因为代码模块显然需要彼此之间的依赖才能工作。这是我的答案:

如果您可以将系统分解为模块,并且可以单独测试这些模块,那么这表明系统是模块化的。

答案 6 :(得分:0)

正如你所说,模块化不是二元的,所以它取决于你的相对定义。

我想说:你能在任何需要执行该功能的程序中使用给定的方法吗?它是“黑匣子”,你不需要知道它在引擎盖下做了什么?如果答案是否定的,即该方法只能在该程序中正常工作,那么它就不是真正模块化的。

答案 7 :(得分:0)

模块化与开发代码的人有关。但我认为普遍的共识是模块化代码是代码,其中包含可以轻松交换的部分,而无需更改大部分原始代码。

恕我直言,如果您有3个模块A B和C,并且您想要完全更改或更换模块C,如果执行此操作是SIMPLE任务,那么您将拥有模块化代码。

答案 8 :(得分:0)

您可以使用代码分析工具(例如CAP)来分析类型和包之间的依赖关系。它们将帮助您查找和删除任何循环依赖项,这在尝试开发模块化代码时通常是个问题。 如果没有循环依赖关系,您可以开始将代码分离为离散的jar。

一般来说,如果可以,最好对接口进行编码,这通常意味着您的代码可以更容易地在不同的上下文中重构和/或使用。

Spring等依赖注入框架也可以帮助您设计的模块化。由于类型通过某些外部配置过程注入其依赖项,因此它们不需要直接依赖于实现。

答案 9 :(得分:0)

package-by-feature这个想法有助于使代码更加模块化。

网上看到的许多例子首先将应用程序划分为多个层,而不是功能

  • 模型
  • 数据访问
  • 用户界面

然而,最好使用与功能对齐的顶级软件包来划分应用程序,而不是

以下是使用逐个功能的网络应用的example。请注意顶级包的名称,它们作为应用程序中实际功能的列表读取。还要注意每个包装如何包含与功能相关的所有项目 - 这些项目不会遍布整个地方;大部分时间,它们都在一个包/目录中。

通常,删除此类应用中的功能可以在一次操作中实现 - 删除单个目录。