JavaScript设计模式_08_模板方法模式
模板方法模式是一种最能体现JavaScript继承的一种设计模式。实现起来也比较简单。由两部分组成,一是抽象父类,另一个是具体的实现子类。在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。
/** * pre:模板方法模式 * 1、一种基于继承的设计模式 * 2、由抽象父类和子类组成,父类封装子类的算法框架以及公共方法, * 子类实现各自不同的部分。 */ //----------- 示例1 ------------- /* coffee - tea */ // 制作coffee var Coffee = function() {}; Coffee.prototype.boilWater = function() { console.log("把水烧开."); }; Coffee.prototype.bubbleCoffee = function() { console.log("开水冲泡咖啡."); }; Coffee.prototype.pourCup = function() { console.log("倒入杯中."); }; Coffee.prototype.addSugarAndMilk = function() { console.log("加糖和牛奶."); }; Coffee.prototype.init = function() { this.boilWater(); this.bubbleCoffee(); this.pourCup(); this.addSugarAndMilk(); }; var coffee = new Coffee(); coffee.init(); // 制作tea var Tea = function() {}; Tea.prototype.boilWater = function() { console.log("把水烧开."); }; Tea.prototype.bubbleTea = function() { console.log("开水冲泡茶叶."); }; Tea.prototype.pourCup = function() { console.log("倒入杯中."); }; Tea.prototype.addLemon = function() { console.log("加入柠檬."); }; Tea.prototype.init = function() { this.boilWater(); this.bubbleTea(); this.pourCup(); this.addLemon(); }; var tea = new Tea(); tea.init(); // --- 抽象转化 ---- var Beverage = function() {}; Beverage.prototype.boilWater = function() { console.log("把水煮沸."); }; Beverage.prototype.bubbleBeverage = function() {}; Beverage.prototype.pourCup = function() {}; Beverage.prototype.addCondiments = function() {}; Beverage.prototype.customerWantsCondiments = function() { return true; }; Beverage.prototype.init = function() { this.boilWater(); this.bubbleBeverage(); this.pourCup(); if(this.customerWantsCondiments()) { this.addCondiments(); } }; // --- coffee --- var Coffee = function() {}; Coffee.prototype = new Beverage(); Coffee.prototype.bubbleBeverage = function() { console.log("开水冲泡咖啡."); }; Coffee.prototype.pourCup = function() { console.log("咖啡倒入杯中."); }; Coffee.prototype.addCondiments = function() { console.log("添加糖和牛奶."); }; Coffee.prototype.customerWantsCondiments = function() { return window.confirm("需要添加糖和牛奶么?"); } var coffee = new Coffee(); coffee.init(); --- tea --- var Tea = function() {}; Tea.prototype = new Beverage(); Tea.prototype.bubbleBeverage = function() { console.log("开水浸泡茶叶."); }; Tea.prototype.pourCup = function() { console.log("茶水倒入杯中."); }; Tea.prototype.addCondiments = function() { console.log("加入柠檬."); } var tea = new Tea(); tea.init(); /* * [钩子方法]:如果在子类中不想实现某些方法,可以在父类定义时设置钩子 */ // ---------- 示例2 -------- /* 真的需要使用继承么? * js是一门灵活的语言,不一定要使用继承这种重武器,可以使用高阶函数. */ var Beverage = function(params) { var boilWater = function() { console.log("把水煮沸."); }; var bubbleBeverage = params.bubbleBeverage || function() { throw Error("必须实现bubbleBeverage方法"); }; var pourCup = params.pourCup || function() { throw Error("必须实现pourCup方法"); }; var addCondiments = params.addCondiments || function() { throw Error("必须实现addCondiments方法"); }; var F = function() {}; F.prototype.init = function() { boilWater(); bubbleBeverage(); pourCup(); addCondiments(); }; return F; }; var Coffee = Beverage({ bubbleBeverage: function() { console.log("用热水冲泡咖啡."); }, pourCup: function() { console.log("把咖啡倒入杯中."); }, addCondiments: function() { console.log("添加糖和牛奶."); } }); var coffee = new Coffee(); coffee.init();
作者:『Stinchan』
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。