0

假设下一节课

interface Thing {
  void doSomething();
}

public class Test {
  public void doWork() {
    //Do smart things here
    ...
    doSomethingToThing(index);
    // calls to doSomethingToThing might happen in various places across the class.
  }

  private Thing getThing(int index) {
    //find the correct thing
    ...
    return new ThingImpl();
  }

  private void doSomethingToThing(int index) {
    getThing(index).doSomething();
  }      
}

Intelli-J 告诉我,我违反了 demeter 定律,因为 DoSomethingToThing 正在使用函数的结果,并且据说您只能调用字段、参数或对象本身的方法。

我真的必须做这样的事情吗:

public class Test {
  //Previous methods
  ...

  private void doSomething(Thing thing) {
    thing.doSomething();
  }

  private void doSomethingToThing(int index) {
    doSomething(getThing(index));
  }
}

我觉得这很麻烦。我认为demeter的法则是一个班级不知道另一个班级的内部,而是getThing()同一个班级!

这真的违反了德米特法则吗?这真的是在改进设计吗?

谢谢你。

4

2 回答 2

0

从技术上讲,这违反了得墨忒耳定律。尽管我认为应该为 LoD-F 考虑私有功能,因为据说它们不能从外部访问。同时,如果“事物”归 Test 所有,它并没有真正违反 Demeter 的法律。但是在 Java 中,获得事物的唯一方法可能是通过 getter,这又回到了技术性(getter 和 action 方法之间没有明确的分离)。

我会说,这样做:

public class Test {
  private Thing getThing(int index) {
    //find the thing
    return thing;
  }

  private void DoSomethingToThing(Thing thing) {
    thing.doSomething();
  }

  private void DoSomethingToThing(int index) {
    DoSomethingToThing(getThing(index));
  }
}

或者,可能更好,让调用者直接使用事物。如果 Test 的功能是生产或公开事物,而不是作为操纵事物的中介,这是可能的。

于 2013-10-23T19:27:18.110 回答
0

IntelliJ 未正确检测对象实例化。

Wikipedia(IDEA 链接到的内容)描述了您可以调用在当前上下文中创建的对象。

这就是我所做的,但我仍然收到警告getMajor()

Version version = Loader.readVersion(inputStream); // Instantiates a new Version

if (version.getMajor() != 2)
    throw new IOException("Only major version 2 is supported");

IDEA 的检查提供了一个选项来忽略对“库”方法的调用。在我的例子中,Loader.readVersion() 一个库方法,但是它位于当前项目中(该项目必须是自支持的)。IDEA 认为它不是库方法。

由于此检查的机制不充分/不完整/幼稚(就像许多IDEA 的检查一样),唯一的解决方案是禁用它并尝试手动避免这些情况。

于 2016-08-10T10:41:07.793 回答