js设计模式 - 适配器模式、装饰器模式
1.适配器模式
适配器模式:(Adapter)是将一个类的接口转化成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。(大话设计模式)
使用场景:系统的数据和行为都正确,但接口不符时,我们应该考虑用适配器,目的时使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用现存的类,但时接口又与服用环境要求不一致的情况。(大话设计模式)
JavaScript 毕竟不是传统基于面向对象的语言 因此使用es6 class关键字(不使用typescript)创建的适配器会和Java、C#、VB.NET的适配器有些许的差异(本文不进行探讨)。
1.1 特定适配器模式
class MyInterface {
constructor(arr) {
this.arr = arr
}
getResult() {
return this.arr
}
}
class MySonInterface extends MyInterface {
transform() {
return this.arr.reduce(function(pre,cur,index,arr) {
pre['date' + index] = cur
return pre
},{})
}
}
var int = new MyInterface([7,2,3,4,5])
var myint = new MySonInterface([7,2,3,4,5])
console.log(int.getResult()); // [7, 2, 3, 4, 5]
console.log(myint.transform()); // {date0: 7, date1: 2, date2: 3, date3: 4, date4: 5}
1.2 通用适配器模式
class Adapter{
constructor(arr) {
this.obj = new MyInterface(arr)
}
transform() {
return this.obj.arr.reduce(function(pre,cur,index,arr) {
pre['date' + index] = cur
return pre
},{})
}
}
var ide = new Adapter([7,2,3,4,5])
console.log(ide.transform()); // {date0: 7, date1: 2, date2: 3, date3: 4, date4: 5}
1.3 工厂适配器模式
class AdapterFactor {
static create (Interface, arr) {
return new Interface(arr)
}
}
var ide2 = AdapterFactor.create(Adapter, [7,2,3,4,5])
console.log(ide2.transform()); // {date0: 7, date1: 2, date2: 3, date3: 4, date4: 5}
2. 装饰器模式
装饰器模式(Decorator Pattern):装饰器模式是指允许一个现有的对象添加新的功能,同时又不改变其结构。使得不同类或者对象之间共享或者扩展一些方法或者行为的时候,更加优雅
使用场景:
2.1 继承实例(❌)
为什么要写一个错误的实例呢?
原因:
1.传统的面向对象的语法中,需要给一个对象新增功能时,我们通常使用的都是类的继承来使某一类对象拥有某个功能。
2.装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。(大话设计模式)
class Cat {
constructor(name) {
this.name = name
}
sayName() {
console.log('猫咪的名字是',this.name);
}
}
class SuperCat extends Cat {
constructor(name,age) {
super(name)
this.age = age
}
sayAge() {
console.log('超级猫咪今年',this.age);
}
}
var cat1 = new Cat('思乡')
var nbCat = new SuperCat('思凡',2)
nbCat.sayName() //猫咪的名字是 思凡
nbCat.sayAge() //超级猫咪今年 2
cat1.sayName() //猫咪的名字是 思乡
因为继承所带来的强耦合性,也导致生成的类有着致命的缺点‘灵活性低’,当我们修改父类的某个属性就会导致子类随之发生更改,由此可以看出类的继承与装饰器模式的区别(如果没有理解,请看装饰器模式的定义)
2.2 装饰器模式实例
class Dog {
constructor(name) {
this.name = name
}
sayName() {
console.log('狗狗的名字是',this.name);
}
}
class SuperDog {
constructor(dog) {
this.dog = dog
}
sayName() {
this.dog.sayName()
}
sayNewname() {
console.log('升级后的超级狗狗拥有了新的名字','超级' + this.dog.name );
}
}
var dog = new Dog('旺财')
var superDog = new SuperDog(dog)
superDog.sayName() //狗狗的名字是 旺财
superDog.sayNewname() // 升级后的超级狗狗拥有了新的名字 超级旺财
dog.sayName() //狗狗的名字是 旺财
由上面的结果可以看出来我们调用superDog的方法的同时我们不仅调用了superDog的方法也调用了Dog的方法,我们只是对其中的Dog进行了一个包装,让我们能在使用Dog类内部方法的同时,我们也能定义新的方法