Java 澄清对「;依赖倒置“;
在查找顶部后,我发现的大多数答案如下:Java 澄清对「;依赖倒置“;,java,oop,design-patterns,solid-principles,Java,Oop,Design Patterns,Solid Principles,在查找顶部后,我发现的大多数答案如下: 高级模块不应依赖于低级模块。二者都 应该依赖于抽象 抽象永远不应该依赖于 关于细节。细节应该取决于抽象 我的理解是这种设计违反了它?因为高级轿车依赖于低级发动机 如果它确实违反了它,解决办法是什么?我想不出别的办法 我也很难理解第二部分“抽象永远不应该依赖于 细节取决于细节。细节应该取决于抽象。”让我重新表述一下你文章中已经存在的内容,看看是否有意义 这是完全可以的汽车是依赖于界面的引擎一样,在您的情况下(只要引擎是注入) 像Car这样的高级模块不应该
- 高级模块不应依赖于低级模块。二者都 应该依赖于抽象
- 抽象永远不应该依赖于 关于细节。细节应该取决于抽象
细节取决于细节。细节应该取决于抽象。”让我重新表述一下你文章中已经存在的内容,看看是否有意义
下面的链接很好地解释了依赖关系倒置的概念: 基本上,它可以归结为复杂类,这取决于简单类的行为,而不是类本身。在您的示例中,以下是依赖项反转的良好实现:
interface Movable {
public void start();
public void throttleUp();
public void throttleDown();
//etc..
}
class Engine implements Movable {
public void start() {
//code
}
//implement other methods
}
class Car {
Movable engine;
public void setEngine(Movable engine) {
this.engine = engine;
}
public void run() {
engine.start();
//code...
}
}
将来你可以制造不同类型的发动机,如汽油、柴油、蒸汽、电。但是只要它们实现了
可移动
,您的汽车就不会改变,因为它是解耦的。您需要理解运行时依赖关系和代码依赖关系之间的区别。Car将始终对引擎实现细节具有运行时依赖性,因为控制流将从Car移动到引擎
然而,依赖项反转是关于源代码依赖项的。您可以使引擎成为接口或抽象类,不同的子类可以提供自己的start()实现(多态性)。这样,您的汽车将只依赖于引擎抽象(在源代码级别),而不依赖于各种start()实现的细节。在编写、编译和部署Car之后,您可以向系统添加新引擎
还要注意,这些原则更像是建议,而不是“总是/从不”规则。使用您自己的判断。关于您回答中“规则”部分的注释:依赖项倒置
是可靠范例的一部分,因此如果您想编写可靠代码,那么您必须遵循这些规则。@Cristik好吧,我不想写“可靠代码”。我想写好代码,虽然“可靠”原则是很好的指导原则,但它们有时会与其他良好的指导原则相矛盾,如KISS ans YAGNI。我不认为SOLID、KISS和YAGNI是相互排斥的,它们针对不同的方面。SOLID处理健壮的代码,YAGNI处理臃肿但正确的代码,而KISS处理可能变得复杂的代码。你可以尊重所有三个(尽管我必须说我发现很难只遵循其中一个:)@Cristik在开始为每个类定义接口之前,你应该阅读这个问题的答案:我没有说我将为每个类定义接口:)
interface Movable {
public void start();
public void throttleUp();
public void throttleDown();
//etc..
}
class Engine implements Movable {
public void start() {
//code
}
//implement other methods
}
class Car {
Movable engine;
public void setEngine(Movable engine) {
this.engine = engine;
}
public void run() {
engine.start();
//code...
}
}