松散的耦合,高凝聚力 可维护的应用程序
这是我一遍又一遍听到的战斗呐喊。关于如何松散耦合组件,有很多建议。
然而,我觉得我从来没有真正听到任何增加凝聚力的具体建议。有没有人可以提供?
你可以在那里开始回答,但我有具体情况,我也希望得到建议。
我有一个相当松散耦合的C#Windows Forms MVP应用程序,它将许多组件基于接口,通过构造函数注入它们并使用Inversion of Control容器(Castle Windsor)将它们组合在一起。
我会说它设计得很好 - 它已经经历了几次大的变更请求并且很容易处理它们。我总体上对它非常满意,但我不能放弃一个唠叨的怀疑,即它不是特别有凝聚力。对于我作为唯一的开发人员来说,这不是问题,但我担心第一次进入应用程序的人可能会感到非常困惑。
让我举个例子 - A公司使用该应用程序来填充和处理带有产品的出货卡车。这意味着有一个 OutgoingTransactionInfo 对象,一个 OutgoingTransactionInfoControl (用于实际输入所述信息), OutgoingTransactionValidator 和 OutgoingTransactionPersister 。随着应用程序的投入生成,我们也收到了处理传入事务的请求 - 这些请求附加了不同的信息,不同的验证以及不同的持久化方式。然后公司B也希望将这个应用程序用于他们的事务处理,这个想法是相似的,但信息,验证,持久性,以及其他一些组件可能会有所不同。
由于我的应用程序具有良好的测试套件并且松散,因此我能够非常轻松地满足这些要求。但是我认识到,在无效状态下意外配置它太容易了。例如,您可以在使用 IncomingTransactionValidator 进行验证时连接它以使用 OutgoingTransactionInfo 对象。如果差异很小,那么错误甚至可能在一段时间内未被发现。
你对我有什么建议吗?您使用了哪些技术来降低此类风险?
答案 0 :(得分:3)
凝聚力意味着您不会将不相关的东西放在一个模块中(类,...)。根据你的描述,你似乎做得很好。正确的测试(你似乎也做了)应该控制风险。
您可能可以使用类型系统(泛型/模板)来确保信息及其验证器相互配合,并可能保存一些代码/使其更加统一(确保增加的复杂性是值得的)。
否则保持良好的工作。
答案 1 :(得分:1)
当系统的每个组成部分专注于一项责任时,您就可以实现高度凝聚力的系统。俗话说“做一件事做得好”。当你觉得一个班级开始做“太多”时,你可以把它重构成两个或更多的课程,每个课程都要负责一件事。这会导致松散耦合:因为每个职责都被定位到特定的类,所以这些类更可能彼此之间具有非常不连续的交互。
快速建议您的接线问题:您的OutgoingAbc类无法检查以确保它在连接在一起时接收OutgoingXyz并且如果类型错误则抛出异常?
答案 2 :(得分:1)
想到的一件事是控制可见性。 (我会用Java来讲,但我想这些概念转移到其他语言)。什么可以“看到” OutgoingTransactionValidator ?在 my.org.outgoing 包之外可以看到它是否合法?
因此,可以通过不宣布某些公开来控制错误接线。
将此概念作为一个进一步的阶段OSGi允许您显式声明捆绑包导出哪些包以及捆绑包使用哪些包,因此依赖关系变得更加明确和受控制。
答案 3 :(得分:1)
Jim Weirich就2009年Mountain West Ruby会议的Ruby观点中的耦合和凝聚问题提供了一个有趣的presentation。处理不同的学位以及何时可能适合或不适合。