初识模块方法模式

模块方法模式

看看怎么“泡咖啡”和“泡茶”。

//泡咖啡
class Coffee{
    prepareRecipe(){
        this.boilWater();
        this.brewCoffeeGrinds();
        this.pourInCup();
        this.addSugarAndMilk();
        
    }
    boilWater(){
        console.log("boil water");
    }
    brewCoffeeGrinds(){
        console.log("brew coffee grinds");
    }
    pourInCup(){
        console.log("pour in cup");
    }
    addSugerAndMilk(){
        console.log("add suger and milk");
    }   

}
//泡茶
class Tea{
    prepareTea(){
        this.boilWater();
        this.steepTeaBag();
        this.pourInCup();
        this.addLemon();
        
    }
    boilWater(){
        console.log("boil water");
    }
    steepTeaBag(){
        console.log("steep tea bag");
    }
    pourInCup(){
        console.log("pour in cup")
    }
    addLemon(){
        console.log("add lemon");
    }
}

在这里插入图片描述
“泡咖啡”和“泡茶”,步骤是一样的:煮、泡、倒、加。区别在于“泡什么”,“加什么”。
为此,抽象出一个超类:CoffeineBeverage

abstract class CoffeineBeverage{
    prepareRecipe(){
        this.boilWater();
        this.brew();
        this.pourInCup();
        this.addCondiments();
    }
    boilWater(){
        console.log("boil water");
    }
    pourInCup(){
        console.log("pour in cup");
    }
    abstract brew();
    abstract addCondiments();
}

CoffeeTea均属咖啡因饮料CoffeineBeverage,它们的泡制过程也是一样的:prepareRecipe(),都将经历
boilWater()brew()pourInCup()addCondiments()四个步骤。至于brew()时的原料是什么,addCondiments()时加的调料是什么,这些细节的控制权交给子类,子类自己说了算。

//泡咖啡
class Coffee extends CoffeineBeverage{
    brew(){
        console.log("brew coffee grinds");
    }
    addCondiments(){
        console.log("add suger and milk");
    }
}
//泡茶
class Tea extends CoffeineBeverage{
    brew(){
        console.log("steep tea bag");
    }
    addCondiments(){
        console.log("add lemon");
    }
}
//测试代码
var coffee = new Coffee();
coffee.prepareRecipe();
console.log("---------分割线---------");

var tea = new Tea();
tea.prepareRecipe();

测试结果:
在这里插入图片描述
抽象类CoffeineBeverage就是模块方法模式,它控制了做事情的总体步骤,但每个步骤的实现细节它不负责,而是由继承它的子类去控制、去实现,因此模块方法常用于框架中。
模块方法并不一定就长得和CoffeineBeverage一样,像Array.prototype.sort()就是模块方法模式,它能够对数组元素进行排序,但怎么个排法,升序?降序?还是按照其他规则,你说了算。

var arr = [1,2,3,4];
//升序排列
var ascendingOrder = function(a,b){
    if(a>b) return 1;
    else if(a<b) return -1;
    else return 0;
}

//降序排列
var descendingOrder = function(a,b){
    if(a<b) return 1;
    else if(a>b) return -1;
    else return 0;
}

arr.sort(ascendingOrder);
console.log(arr);//输出 [ 1, 2, 3, 4 ]


arr.sort(descendingOrder);
console.log(arr);//输出 [ 4, 3, 2, 1 ]
Hook(钩子)
abstract class CoffeineBeverage{
    prepareRecipe(){
        this.boilWater();
        this.brew();
        this.pourInCup();
        if(this.wantsCondiments()){
            this.addCondiments();
        }
    }
    boilWater(){
        console.log("boil water");
    }
    pourInCup(){
        console.log("pour in cup");
    }
    abstract brew();
    abstract addCondiments();
    wantsCondiments():boolean{
        return true;
    };
}
class Coffee extends CoffeineBeverage{
    brew(){
        console.log("brew coffee grinds");
    }
    addCondiments(){
        console.log("add suger and milk");
    }
}
class Tea extends CoffeineBeverage{
    brew(){
        console.log("steep tea bag");
    }
    wantsCondiments(){
        return false;
    }
    addCondiments(){
        console.log("add lemon");
    }
}

抽象类CoffeineBeverage中有个方法wantsCondiments(),默认返回trueCoffee直接继承了该方法,所以泡咖啡时默认加糖和牛奶。
Tea中覆写了wantsCondiments(),返回false,因此,泡茶时不用加柠檬。
wantsCondiments这个方法就是一个钩子,它让addCondiments()成了一个可选项,子类也因此有了选择的权利。
在这里插入图片描述
这让我想到了webpack钩子
如果把webpack的编译打包过程比作是一个输入输出系统,这个系统就是一个黑盒,我们只关注输入输出。其中,输入就是我们配置的文件webpack.config.js,输出就是编译打包得到的文件
默认情况下,webpack会根据一定的策略将webpack.config.js配置的参数和webpack本身的默认参数进行合并,得到一个汇总参数,然后依照这个汇总参数设置的规则一路编译打包,输出结果。而webpack提供的形如this.hooks.XXX钩子则让我们有机会改变其默认行程,从而跳过某些默认步骤或者预设某些动作以便对后面可能发生的事情做出反应。
钩子在现在的各种前端框架中很常见,找个机会再深入了解。
补充:举例和主要思想来自<HeadFirst设计模式>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值