“这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战”前端
在面试高级前端时,每每会遇到一些关于设计模式的问题,每次都回答不太理想。恰逢8月更文挑战的活动,准备用一个月时间好好理一下关于设计模式方面的知识点,给本身增长点面试的底气。web
在学习设计模式以前,首先要认识到设计模式是个编程思想,对任何编程语言都适用。其次要从设计模式的原则开始学习,故本文将详细介绍设计模式的原则之一依赖倒置原则。面试
高层模块不该该依赖低层模块。两个都应该依赖抽像。编程
抽像不该该依赖细节,细节应该依赖抽像。设计模式
首先举几个生活中的例子来了解一下高层模块和低层模块。markdown
电脑主机你们都很熟悉吧,主机中有主板、CPU、内存条、显卡、硬盘,其中主板属于高层模块,CPU、内存条、显卡、硬盘属于低层模块。这么归属是由必定依据的,低层模块具有易换性,高层模块具有不易替换性。试想一下,换一个主板,要先把CPU、内存条、显卡、硬盘拆掉,而后再更换主板,要动到全部配件。那么换一个内存条呢,只要把内存条从主板上把下来替换上去就行。编程语言
再举一个例子加深一下对高层模块的不易替换性和低层模块的易替换性的理解。假设你开了一家奶茶店,其中奶茶店就是高层模块,所卖的奶茶是低层模块。在生意很差的时候,换几种奶茶卖容易,仍是从新开一家奶茶店容易。post
高层模块可看做一个平台,把低层模块放在这个平台上,才能实现其做用。好比把CPU、内存条、显卡、硬盘安置到主板上才能其做用,把奶茶放在奶茶店中才能卖出去。学习
理解完什么是高层模块和低层模块,再来理解一下为何要依赖倒置,倒置是如何操做的。仍是用开奶茶店的例子来作解释。this
假设你要开一家奶茶店,按正常人思惟,先想要在哪里开店,要请多少员工,最后在决定卖什么奶茶。然而有些老板想太多了,都想到要如何生产奶茶了。这就是本末倒置了,应该是奶茶依赖奶茶店才能卖出去,因此要依赖倒置一下。这也是依赖倒置原则中的高层模块不该该依赖低层模块,奶茶店不该该依赖奶茶,奶茶种类千千万万,大不了换一种奶茶就行。
上面提到过奶茶依赖奶茶店才能卖出去,还要再补充一下,奶茶不能应该一家奶茶店,这家奶茶店倒闭了,换一家奶茶店卖就是了。这样奶茶店和奶茶之间都不互相依赖了,这也不行。根据依赖倒置原则中的两个都应该依赖抽像来解决该问题。用代码来模拟一下解决过程,从千千万万奶茶(具体类)中抽像出一个抽像类MilkTea
,由于规定了奶茶(具体类)中必须提供一个sell
方法来卖奶茶,因此在抽像类MilkTea
中实现一个sell
方法来卖奶茶,sell
方法接收一个奶茶(具体类)实例化后的对象,执行对象中的sell
方法,就是卖奶茶。
在奶茶店(高层模块)中继承抽像类MilkTea
建立了一个备货的功能Stock
类,老板执行new Stock([AMilkTea, BMilkTea, CMilkTea])
,[AMilkTea, BMilkTea, CMilkTea]
为要备货奶茶种类清单,获得一堆奶茶goods
,而后有人来买AMilkTea奶茶,老板就执行goods.sellTea(AMilkTea)
,如何AMilkTea奶茶有生产,就会返回“卖出一杯A奶茶”,没有生产,则返回“该种奶茶未生产”。在此过程,奶茶店(高层模块)不要去管奶茶(低层模块)如何生产(实例化),如何一种奶茶(低层模块)停产了(删除了),也不会影响奶茶店的正常营业,只要告诉顾客“该种奶茶未生产”。
class MilkTea {
sell(milkTea) {
if (milkTea.sell instanceof Function) {
milkTea.sell();
}else{
console.log('该种奶茶暂不销售')
}
}
}
class Stock extends MilkTea {
constructor(teaTypes) {
super();
this.teas = {};
teaTypes.forEach(item => {
const tea = new item();
this.teas[item] = tea;
})
}
sellTea(teaType) {
if (this.teas[teaType]) {
this.sell(this.teas[teaType])
} else {
console.log('该种奶茶未生产')
}
}
}
class AMilkTea {
constructor() {}
sell() {
console.log('卖出一杯A奶茶')
}
}
class BMilkTea {
constructor() {}
sell() {
console.log('卖出一杯B奶茶')
}
}
const goods = new Stock([AMilkTea, BMilkTea, CMilkTea]);
goods.sellTea(AMilkTea);// 卖出一杯A奶茶
goods.sellTea(BMilkTea);// 卖出一杯B奶茶
goods.sellTea(CMilkTea);// 该种奶茶未生产
复制代码
其中if (milkTea.sell instanceof Function)
体现了依赖倒置原则中的抽像不该该依赖细节,细节应该依赖抽像,若是一个奶茶(低层模块)没有提供卖奶茶的方法,那就不卖了(不执行),不会影响奶茶店营业(程序正常运行),只需告诉顾客“该种奶茶暂不销售”。