贯穿javascript类的设计模式——模板方法模式

这是我参与更文挑战的第17天,活动详情查看:更文挑战

模板方法模式是一种只需要使用继承就可以实现的非常简单的模式。模板方法模式由两部分组成:抽象父类和实现子类。

下面是泡咖啡和泡茶的例子:

Coffee or Tea

// Coffee
class Coffee {
    constructor() {
        this.boilWater(); // 把水烧开
        this.brewCoffeeGriends(); // 冲泡咖啡
        this.addSugarAndMilk(); // 加糖和牛奶
    }

    boilWater() {
        console.log('把水烧开');
    }

    brewCoffeeGriends() {
        console.log('冲泡咖啡');
    }

    addSugarAndMilk() {
        console.log('加糖和牛奶');
    }
}

const coffee = new Coffee();

// Tea
class Tea {
    constructor() {
        this.boilWater(); // 把水烧开
        this.steepTeaBag(); // 泡茶
        this.addLemon(); // 加柠檬
    }

    boilWater() {
        console.log('把水烧开');
    }

    steepTeaBag() {
        console.log('泡茶');
    }

    addLemon() {
        console.log('加柠檬');
    }
}

const tea = new Tea();
复制代码

可以看出来在冲泡咖啡和茶的时候,它们的步骤很相似。我们知道,它们两个只是不同的热饮而已,可以看做类似的制作步骤的东西,我们下面创建一个父类,抽象出来。

创建一个抽象父类

// HotBeverage
class HotBeverage {
    constructor() {
        this.boilWater();
        this.brew();
        this.addCondiments();
    }

    boilWater() {
        console.log('把水烧开');
    }

    brew() {} // 空函数,让子类进行复写

    addCondiments() {} // 空函数,让子类进行复写

}

class Coffee extends HotBeverage {
    constructor() {
        super();
    }

    brew() {
        console.log('冲泡咖啡');
    }

    addCondiments() {
        console.log('加糖和牛奶');
    }
}

class Tea extends HotBeverage {
    constructor() {
        super();
    }

    brew() {
        console.log('泡茶');
    }

    addCondiments() {
        console.log('加柠檬');
    }
}

const coffee = new Coffee();
const tea = new Tea();
复制代码

这里的父类执行了三步,烧水,冲泡,加东西。两个子类对其继承分别实现了自己的方法。我们也可以在子类中实现自己想要的方法,或者父类的某个方法并不是所有子类都需要的,只是适用于部分场景。

进一步改造子类

class HotBeverage {
    constructor(opts) {
        this.boilWater();
        this.brew();
        this.addCondiments();
        if(opts && opts.needTool) {
            this.addTool();
        }
    }

    boilWater() {
        console.log('把水烧开');
    }

    brew() {}

    addCondiments() {}

    addTool() {}

}

class Coffee extends HotBeverage {
    constructor(opts) {
        super(opts);
    }

    brew() {
        console.log('冲泡咖啡');
    }

    addCondiments() {
        console.log('加糖和牛奶');
    }

    addTool() {
        console.log('配把勺子');
    }

}

class Tea extends HotBeverage {
    constructor() {
        super({needTool: false});
    }

    brew() {
        console.log('泡茶');
    }

    addCondiments() {
        console.log('加柠檬');
    }
}

const coffeeNeedTool = new Coffee({needTool: true});
const coffee = new Coffee();
const tea = new Tea();
复制代码

这里给HotBeverage新增了一个方法,加上喝饮料的工具,一般咖啡都会需要一把勺子用来搅拌,而热茶一般不需要。我们可以让其需要的时候传入对应的参数就可以了,默认不需要勺子。

引用

[1] 曾探:JavaScript设计模式与开发实践

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享