Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 耦合、内聚与德米特定律_Oop_Refactoring_Coupling_Law Of Demeter_Cohesion - Fatal编程技术网

Oop 耦合、内聚与德米特定律

Oop 耦合、内聚与德米特定律,oop,refactoring,coupling,law-of-demeter,cohesion,Oop,Refactoring,Coupling,Law Of Demeter,Cohesion,指示您应该只与您直接了解的对象交谈。也就是说,不要执行方法链接来与其他对象对话。当您这样做时,您正在和中间对象建立不正确的链接,将您的代码不适当地连接到其他代码 那太糟糕了 解决方案是让您知道的类本质上公开简单的包装器,将责任委托给与其有关系的对象 那很好 但是,这似乎导致了班级的低收入。它不再仅仅负责它所做的事情,它还拥有委托,从某种意义上说,通过复制其相关对象的接口部分,使代码的内聚性降低 那太糟糕了 它真的会降低内聚力吗?这是两害相权取其轻吗 这是发展的灰色地带之一,在这里你可以辩论界线在

指示您应该只与您直接了解的对象交谈。也就是说,不要执行方法链接来与其他对象对话。当您这样做时,您正在和中间对象建立不正确的链接,将您的代码不适当地连接到其他代码

那太糟糕了

解决方案是让您知道的类本质上公开简单的包装器,将责任委托给与其有关系的对象

那很好

但是,这似乎导致了班级的低收入。它不再仅仅负责它所做的事情,它还拥有委托,从某种意义上说,通过复制其相关对象的接口部分,使代码的内聚性降低

那太糟糕了

它真的会降低内聚力吗?这是两害相权取其轻吗


这是发展的灰色地带之一,在这里你可以辩论界线在哪里,或者有没有强有力的、有原则的方法来决定界线在哪里,以及你可以使用什么标准来做出决定?

在耦合和内聚之间似乎存在权衡的情况下,我可能会问自己“如果其他人已经编写了此逻辑,而我正在查找其中的错误,我将首先查找哪里?”,然后以这种方式编写代码。

如果您使用

int price = customer.getOrder().getPrice();
解决方案不是创建getOrderPrice()并将代码转换为

int price = customer.getOrderPrice();

但要注意的是,这是一个很好的方法,并进行相关的更改,希望既能提高内聚性又能降低耦合性。不幸的是,这里没有简单的重构总是适用的,但您可能应该应用,我不知道这是否真的会降低内聚性

聚合/组合都是关于一个类利用其他类来满足它通过其公共方法公开的契约。 该类不需要复制其相关对象的接口。它实际上对方法调用方隐藏了关于这些聚合类的任何knowldge

要在多个级别的类依赖关系中遵守Demeter定律,只需在每个级别应用聚合/组合和良好的封装


换句话说,每个类对其他类都有一个或多个依赖项,但是这些依赖项只对引用的类有依赖项,而不依赖于从属性/方法返回的任何对象。

我想您可能误解了内聚的含义。一个用其他几个类实现的类不一定有ow Ne聚力,只要它代表一个清晰的概念,并且有一个明确的目的。例如,您可能有一个
班级人员
,它是根据班级
日期
(出生日期),
地址
,以及
教育
(该人员就读的学校列表)来实现的。您可以在
Person
中提供包装,以获取出生年份、该人上一所学校或他居住的州,以避免暴露
Person
是根据其他类实现的这一事实。这将减少耦合,但会使
Person
的凝聚力丝毫不减。

这是一个gr安永地区。 这些原则是为了在工作中帮助你,如果你发现你在为他们工作(即,他们妨碍了你的工作和/或你发现它使你的代码过于复杂),那么你就太难遵守,你需要退让

让它为你工作,不要为它工作。

Grady Booch在“面向对象的分析和设计”中:

“凝聚力的理念也来自结构化设计。简单地说,就是凝聚力 测量单个模块(和)元素之间的连接程度 对于面向对象设计,一个类或对象)。最不可取的形式 衔接是一种巧合的衔接,在这种衔接中,完全不相关的抽象是一致的 抛出到同一类或模块中。例如,考虑一个类包括 狗和宇宙飞船的抽象,它们的行为是完全不相关的。这个 最理想的衔接形式是功能衔接,其中 一个类或模块一起工作以提供一些良好的有界行为。 因此,如果类Dog的语义包含行为,那么它在功能上是内聚的 一条狗,整条狗,除了狗什么都没有。”

在上面用Customer代替Dog,这可能会更清楚一些。因此,我们的目标实际上只是为了实现功能性内聚,并尽可能地远离巧合性内聚。这取决于您的抽象,可能很简单,也可能需要一些重构

注:内聚适用于一个“模块”而不是一个单独的类,即一组类一起工作。因此,在这种情况下,Customer和Order类仍然具有良好的内聚性,因为它们具有这种强大的关系,客户创建订单,订单属于客户

马丁·福勒说,他更愿意称之为“德米特的建议”(见文章):

“模拟测试人员确实更多地讨论了避免‘火车失事’——getThis().getThat().getTheOther()风格的方法链。避免方法链也被称为遵循德米特定律。虽然方法链是一种气味,但中间人对象因转发方法而膨胀的相反问题也是一种气味。(我一直觉得,如果德米特定律被称为德米特的建议,我会对它更为熟悉。)


这很好地总结了我的来历:与严格遵守“法律”相比,具有较低水平的凝聚力是完全可以接受的,而且通常是必要的“可能需要。避免巧合的内聚,以功能内聚为目标,但不要在需要调整的地方挂断电话,以便更自然地适应您的设计抽象。

不过,如果需要定制,请使用另一个海报示例