Javascript 设计模式 - 模板模式 & 适配器模式

1,606 阅读4分钟

模板方法模式(Template Method)

模板方法模式是一种通过封装变化提高系统扩展性的设计模式。

在传统的面向对象语言中,一个运用了模板方法模式的程序中,子类的方法种类和执行顺序都是不变的,所以我们把 这部分逻辑抽象到父类的模板方法里面。而子类的方法具体怎么实现则是可变的,于是我们把这 部分变化的逻辑封装到子类中。通过增加新的子类,我们便能给系统增加新的功能,并不需要改 动抽象父类以及其他子类,这也是符合开放-封闭原则的。

应用场景

假如我们有一些平行的子类,各个子类之间有一些相同的行为,也有一些不同的行为。如果相同和不同的行为都混合在各个子类的实现中,说明这些相同的行为会在各个子类中重复出现。 但实际上,相同的行为可以被搬移到另外一个单一的地方,模板方法模式就是为解决这个问题而生的。在模板方法模式中,子类实现中的相同部分被上移到父类中,而将不同的部分留待子类来实现。这也很好地体现了泛化的思想。

组成

模板方法模式由两部分结构组成:

  • 抽象父类: 通常在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行方式(比如执行顺序、条件执行等)。
  • 具体的实现子类: 子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。

示例

模板方法模式通常通过继承来实现,在 JavaScript 开发中用到继承的场景其实并不是很多,很多时候我们都喜欢用 mix-in 的方式给对象扩展属性。

抽象类定义执行方法的方式(比如执行顺序、条件执行等),它的子类可以按需要重写被执行的方法,核心是抽象类。

class Tax {
  calc(value) {
    if (value >= 1000)
      value = this.overThousand(value);

    return this.complementaryFee(value);
  }
  complementaryFee(value) {
    return value + 10;
  }
}

class Tax1 extends Tax {
  constructor() {
    super();
  }
  overThousand(value) {
    return value * 1.1;
  }
}

适配器模式(Adapter Pattern)

适配器模式的作用是解决两个接口/方法间的接口不兼容的问题。

作为两个不兼容的接口之间的桥梁,就是新增一个包装类,对新的接口进行包装以适应旧代码的调用,避免修改接口和调用代码。

示例

// 1. 方法适配 *******************************
const A = {
    show() {
       console.log('visible');
    }
}
const B = {
    display() {
       console.log('visible');
    }
}
// 不使用适配器
A.show();
B.display();

// 使用适配器
const C = {
    show() {
       B.display();
    }
}
A.show();
C.show();

// 2. 接口适配 *******************************
const data1 = {name: 'alan'};
const data2 = {username: 'tom'};
function sayName(param) {
    console.log(param.name);
}
function adapter(param) {
    return {name: param.username}
}
sayName(data1);
sayName(adapter(data2));

相似模式之间的差异

有一些模式跟适配器模式的 结构非常相似,比如装饰者模式、代理模式和外观模式。

这几种模式都属于“包 装模式”,都是由一个对象来包装另一个对象。区别它们的关键仍然是模式的意图。

  • 适配器模式主要用来解决两个已有接口之间不匹配的问题,它不考虑这些接口是怎样实 现的,也不考虑它们将来可能会如何演化。适配器模式不需要改变已有的接口,就能够 使它们协同作用。
  • 装饰者模式和代理模式也不会改变原有对象的接口,但装饰者模式的作用是为了给对象 增加功能。装饰者模式常常形成一条长的装饰链,而适配器模式通常只包装一次。代理 模式是为了控制对对象的访问,通常也只包装一次。
  • 外观模式的作用倒是和适配器比较相似,有人把外观模式看成一组对象的适配器,但外 观模式最显著的特点是定义了一个新的接口。

总结

适配器模式是作为一个中间的桥梁,使原本有差异的接口变成需要的标准,能够满足现有接口的需要,而不需要去修改现有的源码。

参考

JavaScript设计模式与开发实践