里氏替换及依赖倒置
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方法的实现就是里氏替换。