JS设计模式初识(八)-模板模式

定义

模板方法模式是一种只需使用继承就可以实现的非常简单的模式。模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。通常 在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。相同的方法都被提取到父类, 类似于Java中的继承的模式,父类定义方法, 子类重写方法

8.1 Coffee and Tea

首先分析比较一下泡咖啡和泡茶的流程:

  • 原料不同。一个是咖啡,一个是茶,但我们可以把它们都抽象为“饮料”。
  • 泡的方式不同。咖啡是冲泡,而茶叶是浸泡,我们可以把它们都抽象为“泡”。
  • 加入的调料不同。一个是糖和牛奶,一个是柠檬,但我们可以把它们都抽象为“调料”。

总结为四个步骤

  1. 把水煮沸
  2. 用沸水冲泡饮料
  3. 把饮料倒进杯子
  4. 加调料

8.2 继承的方式实现

    // 饮料
    function Beverage() {}
    Beverage.prototype.boilWater = () => {
        console.log(' => 把水煮沸');
    }
    Beverage.prototype.brew = () => { throw new Error('子类必须重写此方法'); }
    Beverage.prototype.pourInCup = () => { throw new Error('子类必须重写此方法'); }
    Beverage.prototype.addCondiments = () => { throw new Error('子类必须重写此方法'); }
    Beverage.prototype.init = function() {
        this.boilWater();
        this.brew();
        this.pourInCup();
        this.addCondiments();
    }
    
    function Coffee() {} 
    Coffee.prototype = new Beverage();
    Coffee.prototype.brew = () => { console.log(' => 泡咖啡',);}    
    Coffee.prototype.pourInCup = () => { console.log(' => 向杯子倒咖啡',);}       
    Coffee.prototype.addCondiments = () => { console.log(' => 加糖和牛奶',);} 
复制代码

8.3 好莱坞原则-不基于继承

    function Beverage(params) {
        const boilWater = () => { console.log(' => 把水煮沸',); }
        const brew = params.brew && (() => { throw new Error('子类必须重写此方法'); });
        const pourInCup = params.pourInCup && (() => { throw new Error('子类必须重写此方法'); });
        const addCondiments = params.addCondiments && (() => { throw new Error('子类必须重写此方法'); });
        const F;
        F.prototype.init = () => {
            boilWater();
            brew();
            pourInCup();
            addCondiments();
        }
        return F;
    }
    
    const Coffee = Beverage({
        brew: () => { console.log(' => 泡咖啡',);},
        pourInCup: () => { console.log(' => 向杯子倒咖啡',);},
        addCondiments: () => { console.log(' => 加糖和牛奶',);}
    });
    const Tea = Beverage({
        brew: () => { console.log(' => 泡茶',);},
        pourInCup: () => { console.log(' => 向杯子倒茶',);},
        addCondiments: () => { console.log(' => 柠檬',);}
    });
    
    
    const coffee = new Coffee();
    coffee.init();
    
    const tea = new Tea();
    tea.init();
复制代码

8.4 总结

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

转载于:https://juejin.im/post/5d03bd065188255f8906553a

猜你喜欢

转载自blog.csdn.net/weixin_33708432/article/details/93183831