JavaScript模板方法模式与职责链模式实战解析

作者:青柠时间:2026-10-30 21:36:14浏览:149

本文深入解析JavaScript中的模板方法模式与职责链模式。通过咖啡与茶的制备示例,阐述模板方法如何封装算法框架并强制子类实现;利用购物定金场景展示职责链模式如何解耦请求处理,将复杂嵌套逻辑转化为清晰的责任链,提升代码可维护性。

一、模板方法模式

该模式基于继承机制构建,主要由抽象父类与具体实现子类两部分构成。

以制作咖啡(Coffee)和茶(Tea)为例进行说明。

//创建抽象类 -- 饮料
     function Beverage(){}
     Beverage.prototype.boilWater = function(){
         console.log("把水煮沸")
     }
     //抽象的父类方法,具体实现由子类来写
     Beverage.prototype.brew = function(){} //泡
     Beverage.prototype.pourIncup = function(){} //饮料倒进杯子
     Beverage.prototype.addCond = function(){} //加调料
     Beverage.prototype.init = function(){
         this.boilWater();
         this.brew();
         this.pourIncup();
         this.addCond();
     }
     //创建具体子类 coffee and tea
     var Coffee = function (){};
     Coffee.prototype = new Beverage();
     Coffee.prototype.brew = function (){
         console.log("用沸水冲泡咖啡")
     }
     Coffee.prototype.brew = function (){
         console.log("把咖啡倒进杯子")
     }
     Coffee.prototype.brew = function (){
         console.log("加糖和牛奶")
     }
     var coffee = new Coffee();
     coffee.init();
     var Tea = function(){};
     Tea.prototype = new Beverage();
     Tea.prototype.brew = function (){
         console.log("用沸水冲泡茶")
     }
     Tea.prototype.brew = function (){
         console.log("茶倒进杯子")
     }
     Tea.prototype.brew = function (){
         console.log("加柠檬")
     }
     var tea= new Tea();
     tea.init();

Beverage.prototype.init 之所以被称为模板方法,是因为它封装了子类的算法框架,作为算法模板指导子类按照特定顺序执行各个步骤。

抽象方法不包含具体实现逻辑,属于哑方法。子类在继承该抽象类时,必须重写父类的抽象方法。

若子类遗漏实现父类定义的抽象方法,程序应如何处理?

Beverage.prototype.brew = function (){
    throw new Error("子类必须重写父类的brew方法")
}

二、职责链模式

该模式旨在弱化发送者(请求方)与接收者之间的强耦合关系。

一、模板方法模式

以购物支付定金的场景为例进行演示。

 //旧版 order
        //orderType 预付定金类型,code为1 500元定金 code为2 200元定金 code为3 普通用户
        //pay 是否已经支付过定金
        //stock  当前用于普通购买客户的手机内存数量
        var order = function (orderType, pay, stock) {
            if (orderType === 1) {
                if (pay) {
                    console.log("预付500定金并且已支付,得到100元优惠券")
                } else { //定金未支付,降到普通购买
                    if (stock > 0) {
                        console.log("普通购买,无优惠券")
                    } else {
                        console.log("库存不足");
                    }
                }
            }
            if (orderType === 2) {
                if (pay) {
                    console.log("预付200定金并且已支付,得到50元优惠券")
                } else { //定金未支付,降到普通购买
                    if (stock > 0) {
                        console.log("普通购买,无优惠券")
                    } else {
                        console.log("库存不足");
                    }
                }
            }
            if (orderType === 3) {
                if (stock > 0) {
                    console.log("普通购买,无优惠券")
                } else {
                    console.log("库存不足");
                }
            }
        }
        //重构
        var order500 = function(orderType, pay, stock){
            if(orderType ===1 && pay){
                console.log("预付500定金并且已支付,得到100元优惠券")
            }else{
                order200(orderType, pay, stock)
            }
        }
        var order500 = function(orderType, pay, stock){
            if(orderType ===1 && pay){
                console.log("预付500定金并且已支付,得到100元优惠券")
            }else{
                order200(orderType, pay, stock)
            }
        }
        var order200 = function(orderType, pay, stock){
            if(orderType ===2 && pay){
                console.log("预付200定金并且已支付,得到50元优惠券")
            }else{
                orderNormal(orderType, pay, stock)
            }
        }
        var orderNormal = function(orderType, pay, stock){
            if (stock > 0) {
                    console.log("普通购买,无优惠券")
                } else {
                    console.log("库存不足");
                }
        }

将大型函数拆分为三个小型函数,从而消除了大量嵌套的条件分支语句。

然而,这种写法导致 order500 与 order200 之间耦合严重,违反了开放-封闭原则。

如需了解更多设计模式相关知识,可参考本站其他文章:

https://www.jb51.net/article/252965.htm

https://www.jb51.net/article/27973.htm

作者最新文章