Oop 以不改进设计的方式应用德米特定律

Oop 以不改进设计的方式应用德米特定律,oop,coupling,law-of-demeter,cohesion,Oop,Coupling,Law Of Demeter,Cohesion,假设我们有一个男孩类,它试图通过分析女孩的日程安排来安排与女孩的约会(Java示例): Boy.tryArrangeDate()方法显然违反了德米特定律,因为例程.happensAt()调用。解决此问题的方法之一是将日程分析直接移动到Girl,避免依赖GirlRoutine。在这种情况下,这可能是最好的决定之一。男孩课程的RFC将减少 但是,假设我们选择一个不同的方向来解决违反德米特法的问题,并以这种方式更改代码: public class Boy { public boolean try

假设我们有一个
男孩
类,它试图通过分析女孩的日程安排来安排与女孩的约会(Java示例):

Boy.tryArrangeDate()
方法显然违反了德米特定律,因为
例程.happensAt()
调用。解决此问题的方法之一是将日程分析直接移动到
Girl
,避免依赖
GirlRoutine
。在这种情况下,这可能是最好的决定之一。
男孩
课程的RFC将减少

但是,假设我们选择一个不同的方向来解决违反德米特法的问题,并以这种方式更改代码:

public class Boy {

  public boolean tryArrangeDate(Girl girl, Date time) {
    return isFree(girl.getSchedule(), time);
  }

  private boolean isFree(List<GirlRoutine> schedule, Date time) {
    boolean free = true;
    for (GirlRoutine routine : schedule) {
      if (happensAt(routine, time)) {
        free = false;
        break;
      }
    }
    return free;
  }

  private boolean happensAt(GirlRoutine routine, Date time) {
    return routine.happensAt(time);
  }

}
public-class-Boy{
公共布尔值tryArrangeDate(女孩,日期时间){
return isFree(girl.getSchedule(),time);
}
私有布尔值isFree(列表计划、日期时间){
布尔自由=真;
用于(网格路由例程:计划){
如果(发生在(常规、时间)){
自由=错误;
打破
}
}
免费返回;
}
私有布尔偶发事件(GirlRoutine例程,日期时间){
返回例程。偶然事件(时间);
}
}
添加了两个私有方法,只需将调用委托给
女孩
和她的日程表/例程

单独使用的每个方法似乎都没有违反Demeter定律(为了简单起见,让我们将从集合中检索项视为一个基本的无方法调用操作)。但总的来说,我们没有减少这个类的RFC,没有提高内聚性,实际上增加了WMC。讲,不问原则是不保留的。所以,德米特定律得到了满足,但设计仍然是脆弱的

问题: 第二个代码片段(正式)是否真的没有违反德米特定律?


注:问题的目的不是寻找替代解决方案,而是确认/反驳该解决方案符合德米特定律

既然你只是问第二个是否仍然违反了德米特的法律,那么是的,我认为它确实违反了。无论您如何重构
tryArrangeDate
,它都不会改变从
GirlRoutine
调用方法的事实。当德米特定律提到“一个物体的任何方法”时,我认为它指的是其他物体可以接近的方法,即暴露于“外部世界”的方法。第二个代码段中的私有方法只是
tryArrangeDate
的助手方法

最初

当涉及到自己的
GirlRoutine
s时,
Girl
类是“专家”。你必须尽可能把它藏起来,不让别人知道。请记住这一原则

也许你能做到:

Response response = girl.askOut(boy, date);
不要把它读得像女孩和男孩约会一样;我遵循的经验法则(大多数时候)是,从中调用方法的对象是该方法表示的操作的直接对象。在这种情况下,
askOut
的直接对象是Girl实例

Response
类可以包含有关其运行情况的信息,也可以是一些简单的内容,如:

enum Response { ACCEPTED, REJECTED }

这样,一个
Girl
实例就具备了接受或拒绝
Boy
实例请求所需的一切知识。

我看不出在同一类
Boy
的函数调用后面隐藏属性访问如何改变任何事情。你把事情看得太字面了。如果(这是一个理论上的如果)您想要改进这方面的东西,您应该将
isFree
方法移动到
Girl
类中,以便
tryArrangeDate
成为
return Girl.isFree(date)
正如你所说。@Jon在
女孩
班上介绍
是免费的
,这是处理事情的正常方式。这一点我很清楚,在问题的表述中也有描述。我只想检查第二个代码片段是否违反了德米特定律,就是这样!将问题稍作修改,使其更加清晰。谢谢您的回答。问题中的第二个代码段违反了[告诉,不要问][原则。这非常清楚。我的问题是,该代码段是否违反了LoD或notOk,我已经更新了我的答案。我提到告诉,不要问原则的原因是,正如我提供的链接所指出的,它们是齐头并进的。
enum Response { ACCEPTED, REJECTED }