我正在学习 SOLID 原则。在学习“依赖倒置原则”时发现类应该依赖于接口而不是具体类。
这是否意味着不允许组合?另外,聚合是否与 DIP 相同?
作品:
class HPDesktop {
private BluetoothMouse bluetoothMouse;
private BluetoothKeyboard bluetoothKeyboard;
public HPDesktop(){
bluetoothMouse = new BluetoothMouse();
bluetoothKeyboard = new BluetoothKeyboard();
}
}
DIP:(这似乎是一种聚合)
class HPDesktop {
private Mouse mouse;
private Keyboard keyboard;
public HPDesktop(Mouse mouse, Keyboard keyboard){
this.mouse = mouse;
this.keyboard = keyboard;
}
}
不,因为您误解了所讨论的依赖关系类型。
依赖倒置的概念是,高级模块不应该依赖于低级模块的细节,这种低级模块细节的“暴露”被称为“泄漏抽象”
例如,假设我正在用一个新的 Facade 包装一个日志实现,这样我就可以用日志“做更多”的事情,而不像我最近用 Log4j 做的那样。如果我将 Log4j 日志级别作为设计中的元素公开,那么我的 Facade 和 Log4j 日志级别之间就会存在依赖关系,因为我的 Facade 需要 Log4j。
现在,如果我创建了自己的 Facade 日志级别,那么使用我的 Facade 的每个人都无需导入 Log4j 即可使用 Log4j 的日志级别。这意味着,如果我想更改 Facade 内部使用的内容,我可以这样做而不会影响我的 Facade 的用户。
这是如何做到的?好吧,接口提供了反转依赖方向的方法。我直接依赖(在外观中)一个接口,该接口将我的日志级别指定为 Log4j 日志级别,并且某个模块提供这些(直接依赖于同一接口)。
由于 Log4j 现在依赖于接口,但作为服务提供者,而不是外观依赖于 log4j 作为服务提供者,因此“日志级别服务”的“提供”现在被颠倒了。这意味着,将来,如果我想更改实现,我不必重写太多代码,只需重写使用我的新日志级别提供者呈现服务提供的代码。
再强调一次,使用直接依赖的 Facade 客户端必须
提供使用的
log4j
日志级别facade
。使用依赖倒置,我可能必须创建第二组facade
日志级别,但我的客户端的导入将是并且我稍后可以接入不同的 jar 来提供
log level interface
实现,这意味着当我更换后端日志级别提供程序时,我的客户端代码不必改变。