如何让代码模块化?
我有一些Java程序,现在我想知道它是否是模块化的,如果是模块化的,那么模块化到什么程度,因为模块化永远不可能是二进制术语,即0或1。 我如何确定特定代码在很大程度上是模块化的。我想知道如何使代码更加模块化?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我有一些Java程序,现在我想知道它是否是模块化的,如果是模块化的,那么模块化到什么程度,因为模块化永远不可能是二进制术语,即0或1。 我如何确定特定代码在很大程度上是模块化的。我想知道如何使代码更加模块化?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(10)
模块化的一些基准:
有关更多想法,请查看 软件质量上的这篇
简介至于您对让你的代码更加模块化首先你应该问自己上述问题,获得具体的答案,然后看看这个。
基本理念是将应用程序分解为尽可能小的代码片段,并整齐地排列在多个易于理解和访问的目录布局中。
应用程序中的每种方法执行的处理量不得超过所需的最小处理量。将这些方法组合成越来越多的宏观方法应该会引导您回到您的应用程序。
Some Benchmarks for modularity:
For more ideas check out this blurb about modularity and this one on software quality
As for your concern on making your code more modular first you should ask yourself the above questions, obtain specific answers for them and then have a look at this.
The basic philosophy is to break down your application into as small of code fragments as possible, arranged neatly across a multitude of easily understandable and accessible directory layouts.
Each method in your application must do no more than the minimum quanta of processing needed. Combining these methods into more and more macro level methods should lead you back to your application.
关键点是
此类模块系统的一个很好的例子是标准汽车零件,如盘式制动器和汽车音响。
当您制造汽车时,您不想从头开始制造汽车音响。您宁愿购买它并将其插入。您也不希望制动系统影响汽车音响 - 或者更糟糕的汽车音响影响制动系统。
为了回答您的问题“我如何确定特定代码在很大程度上是模块化的”,我们可以提出问题来测试模块化性。 您能否轻松地用其他模块替换您的模块而不影响应用程序的其他部分?
XML 解析器可能是另一个例子。一旦获得 DOM 接口,您实际上并不关心底层使用的是哪种 XML 解析器实现(例如 Apache Xerces 或 JAXP)。
在 Java 中,另一个问题可能是:所有功能都可以通过
接口
访问吗?接口几乎可以解决低耦合问题。另外,您能用一句话描述一下您系统中的每个模块吗?例如,汽车音响播放音乐和收音机。盘式制动器使车辆安全减速。
(这是我写给 什么是组件驱动开发?
的内容 )在 Wikipedia 中,基于组件的开发是基于组件的软件工程 (CBSE) 的别名。
这有点模糊,所以让我们看看更多细节。
因此,根据这个定义,组件可以是任何东西,只要它真正做好一件事并且只做一件事。
所以这听起来越来越像我们认为好的 API 或 SOA 应该是什么样子。
提供的接口由棒棒糖表示,必需接口由附加到 UML 中组件外边缘的开放套接字符号表示。
可替换性和可重用性是组件之所以成为组件的原因。
那么这和面向对象编程有什么区别呢?
Key points are
A good example of such module system is standard car parts like disk brakes and car stereo.
You don't want to build car stereo from scratch when you are building cars. You'd rather buy it and plug it in. You also don't want the braking system affecting the car stereo — or worse car stereo affecting the brake system.
To answer your question, "How do I decide that particular code is modular up to this much extent," we can form questions to test the modularity. Can you easily substitute your modules with something else without affecting other parts of your application?
XML parsers could be another example. Once you obtain the DOM interface, you really don't care which implementation of XML parser is used underneath (e.g. Apache Xerces or JAXP).
In Java, another question may be: Are all functionality accessible via
interface
s? Interface pretty much takes care of the low coupling.Also, can you describe each module in your system with one sentence? For example, a car stereo plays music and radio. Disk brakes decelerate the vehicle safely.
(Here's what I wrote to What is component driven development?)
According to Wikipedia, Component-Based Development is an alias for Component-based software engineering (CBSE).
This is somewhat vague, so let's look at more details.
So, according to this definition, a component can be anything as long as it does one thing really well and only one thing.
So this is sounding more and more like what we think of good API or SOA should look like.
The provided interfaces are represented by a lollipop and required interfaces are represented by an open socket symbol attached to the outer edge of the component in UML.
Substitutability and reusability is what makes a component a component.
So what's the difference between this and Object-Oriented Programming?
要回答如何使代码更加模块化的具体问题,有以下几种方法:
模块化的最佳工具之一是发现代码重用。如果您发现您的代码在多个地方执行完全相同(或非常相似)的操作,那么它是模块化的良好候选者。
确定哪些逻辑可以独立,从某种意义上说,其他逻辑可以使用它们,而无需知道它们是如何构建的。这有点类似于 OO 设计中的内容,尽管模块/组件不一定需要与 OO 中的建模对象相对应。
To answer your specific question of how to make the code more modular, a couple of approaches are:
One of best tool for modularization is spotting code re-use. If you find that your code does the same exact (or very similar) thing in more than once place, it's a good candidate for modularizing away.
Determine which pieces of logic can be made independent, in a sense that other logic would use them without needing to know how they are built. This is somewhat similar to what you to in OO design, although module/component does not necessarily need to correspond to a modeled object as in OO.
Hej,
请参阅“如何封装软件(第 1 部分)”,此处:
http:// /www.edmundkirwan.com/encap/overview/paper7.html
问候,
埃德。
Hej,
See, "How to encapsulate software (Part 1)," here:
http://www.edmundkirwan.com/encap/overview/paper7.html
Regards,
Ed.
由于它已被标记为“osgi”,因此我可以提出与 OSGi 相关的观点。
简短的回答是,可以通过小步骤从完全意大利面条式代码转变为模块化;它不一定是一个大爆炸。例如,即使是意大利面条代码也依赖于某种博洛尼亚日志库,因此从某种意义上说,它已经是模块化的,只是其中包含一个非常大的 Metball(对不起,模块)。
诀窍是将大肉丸分解成一个较小的块,然后再分解成一个稍小的大肉丸,然后递归。这一切也不必一次性完成;只需每次多削一点,直到没有任何东西可以去除为止。
至于 OSGi,仍然可以将 uber-jar 放入捆绑包中。事实上,您可以在不更改位的情况下完成此操作;通过就地修改 Manifest.MF,或者将其包装在另一个 JAR 中并在清单中指定 Bundle-ClassPath:metaball.jar。
如果做不到这一点,BND 等工具可以帮助生成您需要的正确数据,然后可以轻松地将其放入 OSGi 运行时中。但要小心过度耦合的代码,以及与类加载器混在一起的东西——这些会让你陷入困境。
Since this has been tagged with 'osgi', I can throw in an OSGi-related perspective.
The short answer is that it is possible to go from completely spaghetti code to modular in small steps; it doesn't have to be a big bang. For example, even spaghetti code depends on some kind of bolognaise logging library, so in some sense, it's already modular, just with One Very Big Metball (sorry, module) in it.
The trick is to break the big meatball into one smaller chunk and then a slightly less big meatball and then recurse. It doesn't all have to be done in one go either; simply chip off a bit more each time until there is nothing left to remove.
As for OSGi, it's still possible to put an uber-jar into a bundle. In fact, you can do this without changing the bits; either by modifying the Manifest.MF in place, or by wrapping that in another JAR and specify Bundle-ClassPath: metaball.jar in the manifest.
Failing that, tools like BND can help generate the right data you'd need, and then it can be dropped in an OSGi runtime easily enough. But beware of overly coupled code, and stuff that mucks around with classloaders - those will trip you up.
假设我理解你的问题,你想知道是什么使代码模块化,因为代码模块显然需要彼此之间的一些依赖关系才能工作。这是我的答案:
如果您可以将系统分解为模块,并且可以单独测试这些模块,那么这很好地表明系统是模块化的。
Assuming I understand your question, that you want to know what it is that makes code modular, since code modules will obviously need some dependency between each other to work at all. This is my answer:
If you can break your system down into modules, and you can test those modules in isolation, that is a good indication that a system is modular.
正如您所说,模块化不是一个二元的东西,所以它取决于您的相对定义。
我会说:你可以在任何需要执行该功能的程序中使用给定的方法吗?它是一个“黑匣子”吗?您不需要知道它在幕后做什么?如果答案是否定的,即该方法只能在该程序中正常工作,那么它就不是真正的模块化。
As you say modularity is not a binary thing so it depends on your relative definition.
I would say: Can you use a given method in any program where you need to perform that function? Is it the "black box" where you wouldn't need to know what it were doing under the hood? If the answer is no, i.e. the method would only work properly in that program then it is not truely modular.
模块化与开发代码的人相关。但我认为普遍的共识是,模块化代码是具有可以轻松交换的部分而无需更改大部分原始代码的代码。
恕我直言,如果您有 3 个模块 AB 和 C,并且您想完全更改或替换模块 C,如果这样做是一项简单的任务,那么您就有模块化代码。
Modularity is relative to who ever is developing the code. But I think the general consensus is that modular code is code that has portions that can easily be swapped out without changing most of the original code.
IMHO, If you have 3 modules A B and C and you want to change or replace module C completely, if it is a SIMPLE task to do so then you have modular code.
您可以使用CAP等代码分析工具来分析类型和包之间的依赖关系。它们将帮助您找到并消除任何循环依赖关系,这在尝试开发模块化代码时通常是一个问题。
如果不存在循环依赖关系,您可以开始将代码分成离散的 jar。
一般来说,如果可以的话,对接口进行编码是一种很好的做法,这通常意味着您的代码可以更轻松地重构和/或在不同的上下文中使用。
Spring 等依赖注入框架也有助于实现设计的模块化。由于类型是通过某些外部配置过程注入其依赖项的,因此它们不需要对实现的直接依赖项。
You can use a code analysis tool such as CAP to analyse the dependencies between types and packages. They'll help you find and remove any cyclic dependencies, which are often a problem when trying to develop modular code.
If there are no cyclic dependencies, you can start separating your code into discrete jars.
In general it is good practice to code to interfaces if you can, this generally means your code can more easily be refactored and/or used in different contexts.
Dependency injection frameworks such as Spring can also help with the modularity of your design. As types are injected with their dependencies by some external configuration process they don't need a direct dependency on an implementation.
按功能打包的想法有助于使代码更加模块化。
网上看到的许多示例首先将应用程序划分为层,而不是功能
但是,使用与功能而不是层一致的顶级包来划分应用程序似乎更好。
以下是使用按功能打包的 Web 应用程序的示例。请注意顶级包的名称,它读取为应用程序中实际功能的列表。还要注意每个包如何包含与功能相关的所有项目 - 这些项目并没有散布在各处;大多数时候,它们都在一个包/目录中。
通常,删除此类应用程序中的功能可以通过单个操作来实现 - 删除单个目录。
The package-by-feature idea helps to make code more modular.
Many examples seen on the web divide applications first into layers, not features
It seems better, however, to divide applications up using top-level packages that align with features, not layers.
Here is an example of a web app that uses package-by-feature. Note the names of the top-level packages, which read as a list of actual features in the application. Note as well how each package contains all items related to a feature - the items aren't spread out all over the place; most of the time, they are all in a single package/directory.
Usually, deletion of a feature in such an app can be implemented in a single operation - deletion of a single directory.