0

假设,我们有以下Boy类,它试图Girl通过分析她的日程安排来安排日期(Java 中的示例):

public class Boy {

  public boolean tryArrangeDate(Girl girl, Date time) {
    boolean success = true;
    for (GirlRoutine routine : girl.getSchedule()) {
      if (routine.happensAt(time)) {
        success = false;
        break;
      }
    }
    return success;
  }

}

Boy.tryArrangeDate()由于routine.happensAt()调用,该方法显然违反了得墨忒耳法则。解决此问题的方法之一是将进度分析直接Girl移至GirlRoutine. 在这种情况下,这可能是最好的决定之一。类的 RFCBoy将减少。

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

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);
  }

}

添加了两个私有方法,它们只是将调用委托给Girl她的日程安排/例程。

每个单独采用的方法似乎都没有违反得墨忒耳法则(为了简单起见,让我们将从集合中检索项目视为原始的无方法调用操作)。但总的来说,我们并没有减少这个类的 RFC,也没有提高内聚性,实际上增加了 WMC。告诉,不问原则是不保留的。所以,得墨忒耳法则满足了,但设计仍然不稳定。

问题:( 正式)第二个代码片段确实不违反得墨忒耳定律吗?

注意:问题的目的不是寻找替代解决方案,而是确认/反驳该解决方案符合得墨忒耳定律

4

1 回答 1

0

更新

既然你只是问第二个是否仍然违反得墨忒耳法则,那么是的,我认为确实如此。无论你如何重构 tryArrangeDate,它都不会改变它从GirlRoutine. 当得墨忒耳法则提到“对象的任何方法”时,我认为它指的是其他对象可以访问的方法,即暴露于“外部世界”的方法。第二个代码片段中的私有方法只是tryArrangeDate.

起初

Girl涉及到自己GirlRoutine的 s 时,该类是“专家”。您必须尽可能地对其他人隐藏它。记住告诉的原则,不要问

也许你可以这样做:

Response response = girl.askOut(boy, date);

不要像 Girl 实例询问 Boy 实例那样阅读它;我遵循的经验法则(大多数时候)是,您从中调用方法的对象是该方法所代表的操作的直接对象。在这种情况下,直接对象askOut是 Girl 实例。

这个Response类可以有关于它是如何进行的信息,或者它可以是简单的,比如:

enum Response { ACCEPTED, REJECTED }

这样,实例就拥有了接受或拒绝实例请求Girl所需的一切信息。Boy

于 2013-09-07T15:46:50.303 回答