里氏替换及依赖倒置
class Zoo {constructor () {}open () {//我要提前准备好多小动物,并设置好每个小动物的名字及它们的表演节目let cat = new Cat('猫')console.log(cat.catName + cat.canJump());let dog = new Dog('狗')console.log(dog.dogName + dog.canSing());} }class Cat {constructor (name) {this.catName = name;}canJump () {return '能跳'} } class Dog {constructor (name) {this.dogName = name;}canSing () {return '能唱'} }let zoo = new Zoo(); zoo.open();
每个小动物都是那么的独特,我要记住他们所有的名字和行为,如果他们的名字和行为发生变化的时候,我就要去修改open方法, 如果来的新的小动物,我还得修改open。
如果我能发出口令“name”,他们就能爆出各自的名字,口令“show” 他们就能表演多好啊, 我要去训练他们,
class Zoo {constructor () {}open () {//我要提前准备好多小动物,并设置好每个小动物的名字及它们的表演节目let cat = new Cat('猫')console.log(cat.name + cat.show());let dog = new Dog('狗')console.log(dog.name + dog.show());} }class Cat {constructor (name) {this.name = name;}show () {return '能跳'} } class Dog {constructor (name) {this.name = name;}show () {return '能唱'} }let zoo = new Zoo(); zoo.open();
嗯, 好多了, 我不用记住它们独特的名字和行为了,我为他们定义了统一的标准,要求他们听到name就返回名字,听到show就表演行为
我总结出了一个规律,所有带name属性,有show方法的动物都能来动物园,所以我只需要为所有的动物指定一个标准就行了,然后让所有的动物都能遵守它。
class Zoo {constructor () {}open (...animals) {//我要提前准备好多小动物,并设置好每个小动物的名字及它们的表演节目for(let animal of animals) {if (animal instanceof Animal) {console.log(animal.name, animal.show())} else {console.log('你不听我的话,我不要你')}}} }class Animal {constructor (name) {this.name = name;}show () {} } class Cat extends Animal{constructor (name) {super(name)}show () {return '能跳'} } class Dog extends Animal{constructor (name) {super(name)}show () {return '能唱'} }let zoo = new Zoo(); zoo.open(new Cat('猫'), new Dog('狗'));
我指定的标准就是Animal, 它就是一个抽象, 我在动物园的open中不在依赖Cat/Dog而是依赖Animal,这就是依赖倒置,而Cat/Dog对于show方法的实现就是里氏替换。