该得墨忒耳定律指出你应该只给你关于直接了解对象说话。 也就是说,不执行方法链接跟其他物体。 当你这样做,你与中介对象建立联系不当,不恰当地连接你的代码到其他代码。
那很糟。
该解决方案将是你知道基本上暴露简单封装该委托负责它与关系对象的类。
非常好。
但是,这似乎导致具有低班级的凝聚力 。 它不再是简单的正是它负责的,但它也有代表在某种意义上,使得代码通过复制其相关对象的接口部分内聚力较小。
那很糟。
它是否真的导致降低的凝聚力? 它是两两害相权较小?
这是一个发展的灰色地带,在那里你可以讨论,其中线,还是有做的哪里画线的标准是什么,你可以用它来作出这样的决定的决定强,有原则的方式吗?
格雷迪Booch的在“面向对象分析与设计”:
“凝聚的想法也来自结构化设计。简单地说,凝聚力措施单个模块的元件之间的连接程度(和用于面向对象的设计,一个类或对象)。凝聚力的最不理想的形式是巧合凝聚,在该完全无关抽象被投入同样的类或模块。例如,考虑包括狗和航天器,其行为是相当无关的抽象的类。凝聚力的最期望的形式是功能性的凝聚,其中,所述元件一类或模块大家共同努力,提供一些良好的行为界定的。因此,该类狗功能凝聚力,如果其语义拥抱狗,整个狗,并没有什么,但狗的行为“。
替补多狗在上面的客户,它可能是一个有点清晰。 所以,真正的目标是仅仅瞄准功能的凝聚力和移动从偶然的凝聚力尽可能远。 根据您的抽象,这可能是简单的或可能需要一些重构。
注意凝聚力也同样适用于“模块”,而不是一个单一的类,即一起工作的一组类。 因此,在这种情况下,客户和订单班还是有不错的凝聚力,因为他们有这种强烈的relationshhip,为客户创造订单,订单属于客户。
Martin Fowler的说,他觉得更舒服称其为“得墨忒耳的建议”(见文章嘲笑不是存根 ):
“Mockist测试人员做进一步讨论避免‘火车残骸’ - 。。中获得OS 3.0风格方法链()getThat()getTheOther()避免方法链也被称为是继迪米特法则虽然方法链是一种气味,的中间人相反的问题对象臃肿转发方法也有异味。(我一直认为我会更舒服迪米特法则,如果它被称为德米特的建议 。)”
这很好地总结了在那里我来自哪里:它是完全可以接受的,往往需要有凝聚力比严格遵守“法律”的一个较低的水平,可能需要。 避免巧合的凝聚力和瞄准功能的凝聚力,不过不要让她挂在调整在需要的地方,以适应更自然地与你的设计抽象。
如果您是通过具有违反迪米特法则
int price = customer.getOrder().getPrice();
将溶液不创建getOrderPrice()和代码转换成
int price = customer.getOrderPrice();
而是要注意,这是一个代码味道 ,并作出相应的修改有希望增加双方的凝聚力和低耦合。 遗憾的是这里没有简单的重构总是适用的,但你应该申请告知不要问
我想你可能是误解了衔接手段。 这是在其他几类方面实现的类不一定有低凝聚力,只要它代表一个明确的概念,并具有明确的目的性。 例如,你可能有一个class Person
,这是在类的形式实现的Date
(出生日期), Address
和Education
(的人去学校名单)。 您可以提供包装在Person
用于获取出生年份,最后学校的人去了,他住在哪里的状态,以避免公开的事实, Person
是在那些其他类的条款执行。 这将减少耦合,但它会使Person
没少凝聚力。
这是一个灰色地带。 这些原则是为了帮助你在你的工作,如果你发现你的工作对他们(即他们在你的方式和/或你觉得在你的代码复杂),那么你就符合太硬,你需要打退堂鼓了。
让它为你的工作,不要为它工作。
我不知道这实际上降低了凝聚力。
汇聚/成分都是关于利用其他课程,以满足通过其公共方法它暴露的合同类。 类并不需要复制该接口的它的相关对象。 它实际上是对隐藏在方法调用者聚集的这些类的任何knwowledge。
服从得墨忒耳定律类依赖的多层次的情况下,你只需要在每个级别应用聚合/组合和良好的封装。
换句话说,每个类都有对其他类的一个或多个依赖,但这些都只是曾经依赖关系上所引用的类,而不是在任何物体从性的判定/方法返回。
在那里似乎是耦合和凝聚力之间的权衡的情况下,我可能会问自己:“如果别人已经写了这个逻辑,我正在寻找其中存在一个bug,在那里我会先看看吗?”,并编写代码的方式。