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();
posted @ 2017-06-20 14:56  Stinchan  阅读(138)  评论(0编辑  收藏  举报