写点什么

命题作业—第二周

用户头像
于江水
关注
发布于: 2020 年 06 月 15 日

请描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?

依赖倒置原则,可以延伸出下面问题:依赖是什么?倒置是什么?避免依赖倒置要解决的问题是什么?

这里的依赖其实是指高层模块与底层模块,抽象与实现之间的依赖关系。倒置则是说依赖的方向反了。避免依赖倒置要解决的问题实际上是提供一种实践去解耦这些依赖。

举例:按钮与灯光控制需求

按钮既可以用于开关灯光,也可以用于让喇叭发声或者关闭,也可以做其他事情。在编写代码实现摁下按钮开关灯光的时候,我们往往会写出如下代码:

class Button {
constructor(status) {
this.status = status || 'off';
}
press() {
if (this.status === 'on') {
this.status = 'off';
Light.off();
} else {
this.status = 'on';
Light.on();
}
}
}
const button = new Button();
button.press();

这样写比较常见和直接,当我切换按钮,就是要开关灯光,但是违背了依赖倒置原则。我们的 Button 属于更高层组件,灯光则属于更下层,当我们在更高层组件中引入了操作下层的代码,就产生了依赖,相对于正确的依赖顺序(下层依赖上层)出现了倒置,违反了依赖导致原则。

违反了有什么后果呢?很明显会导致 Button 组件不够复用,跟 Light 组件产生了耦合。当我们需要为蜂鸣器编写一个 Button 切换的时候,这个 Button 组件就无法复用了,需要重新编写冗余代码。

那么如何解决这个问题呢?应该让 Light 等下层组件去依赖 Button,而对 Button 组件做好自身能力封装。比如 Button 就提供状态和调用 on off 的方法的能力,但是不对 on off 的内容做判断。然后将下层组件对照接口进行实现:

class Button {
constructor(status, handler) {
this.status = status || 'off';
this.handler = handler;
}
press() {
if (this.status === 'on') {
this.status = 'off';
handler.off();
} else {
this.status = 'on';
handler.on();
}
}
}
const lightButton = new Button('off', {
on: Light.on,
off: Light.off
});
lightButton.press();
const soundButton = new Button('off', {
on: Sound.on,
off: Sound.off
});
soundButton.press();

这样 Button 就可以复用了。

好莱坞原则是 Don't call me, I'll call you. 上面案例可以看出,Button 会在合适的机会 call 下层组件的对应方法,下层组件需要针对上层组件的接口进行实现。

请描述一个你熟悉的框架,是如何实现依赖倒置原则的?

webpack 的 loader 机制

webpack 在打包构建的时候,针对输入的不同的文件类型,会使用对应的 loader 去实现具体的加载逻辑,之后负责调用相关方法并打包合并在一起。

webpack 就是上层依赖,提供了接口,具体的 loaders(css-loader、ts-loader 等)将会实现这个接口和具体的业务逻辑,这样就依赖了 webpack。

之后实际打包过程中,webpack 就可以针对不同文件调用不同 loader 进行打包和流程控制。

请用接口隔离原则优化 Cache 类的设计,画出优化后的类图







发布于: 2020 年 06 月 15 日阅读数: 70
用户头像

于江水

关注

还未添加个人签名 2018.07.08 加入

还未添加个人简介

评论 (2 条评论)

发布
用户头像
文中Button的例子是如何提现依赖倒置的
2020 年 06 月 23 日 21:24
回复
Button 定义接口 on 和 off,如果你想复用这个 Button 的操作,需要按照这个接口开发你的组件,然后实现这个接口依赖。所以第一个 case 中,Button 依赖了 Light 的实现,依赖倒置导致了强耦合,后面的 case 中 Button 不管你是什么,通过传入标准的组件实现扩展和复用 Button 的能力。
2020 年 06 月 29 日 17:36
回复
没有更多了
命题作业—第二周