假设下一个课程
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()
属于同一类!
这真的违反了德米特的规律吗?这是真正改善的设计吗?
谢谢。
答案 0 :(得分: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的功能是产生或暴露事物,而不是作为操纵事物的媒介,那么这是可能的。
答案 1 :(得分:0)
IntelliJ未正确检测对象实例化。
Wikipedia(与IDEA相关的链接)描述了您可以调用在当前上下文中创建的对象。
这就是我的所作所为,但我仍在flatMap()
收到警告:
optionalIntegers.stream()
.flatMap(o -> o.map(Stream::of)
.orElse(Stream.empty()))
.forEach(integers::add);
IDEA的检查提供了忽略对图书馆'方法。就我而言,getMajor()
是库方法,但它位于当前项目内(项目必须是自我支持的)。 IDEA认为它不是图书馆方法。
由于这次检查的机制不充分/不完整/天真(比如很多的IDEA检查btw),唯一的解决方案是禁用它并尝试手动避免这些情况。