模板方法模式

定义:只需使用原型链继承就可以实现简单的模式

组成:由抽象的父类和具体实现的子类组成。抽象父类封装子类的算法框架,公共方法和封装子类中所有方法的执行顺序方法。子类通过继承抽象类,可以重写父类方法

应用场景:模板方法模式常用于搭建项目的框架,定好框架的骨架,然后继承框架的结构之后,往里面添加功能;

web开发中,搭建一系列的UI组件,组件的构建过程:

1)初始化一个div容器

2)通过ajax请求拉取到相应的数据

3)把数据渲染到div容器里面,完成组件构造

4)通知用户组件渲染完毕

1)、4)相同,子类只需要重写2)、3

模板方法模式中的钩子方法:用于解决一些特例,隔离变化。在父类中容易发生变化的地方放置钩子,钩子有一个默认的实现,由子类决定要不要挂钩。钩子方法的返回结果决定模板方法后面的执行步骤
茶与咖啡例子

<!doctype html>
<html>
    <head>
        <meta charset="utf-8"/>
        <script src="jquery-3.1.1.min.js"></script>
    </head>
    <body>
      <button id='btn'>execute command</button>
      <script>
          /**********抽象父类,泡一杯饮料的整个过程*********/ 
          let Beverage = function(){};
          //下面3个空方法,由子类重写,父类提供接口 
          Beverage.prototype.boilWater = function(){
            console.log('把水煮沸');
          };
          // 防止子类没有重写这些方法带来的错误
          Beverage.prototype.brew = function(){
            throw new Error('子类必须重写brew');
          };
          Beverage.prototype.pourInCup = function(){
            throw new Error('子类必须重写pourInCup');
          };
          Beverage.prototype.addCondiments = function(){
            throw new Error('子类必须重写addCondiments');
          };
          // 钩子方法,true-表示挂钩,false-表示不挂钩,默认为true
          Beverage.prototype.customerWantsCondiments = function(){
            return true;
          };
          //这个就是模板方法,封装子类的算法框架,指导子类以何种顺序执行哪些方法
          Beverage.prototype.init = function(){
            this.boilWater();
            this.brew();
            this.pourInCup();
            // 这里需要判断钩子方法的返回值,做下一步的处理
            if( this.customerWantsCondiments() ){ //挂钩返回true,表示加饮料
              this.addCondiments();
            } 
          };
 
          /*******创建子类Coffee,继承父类,并且重写父类中的方法********/ 
          let CoffeeWithHook = function(){};
          // 通过原型链继承父类
          CoffeeWithHook.prototype = new Beverage();
          // 重写父类中的方法
          CoffeeWithHook.prototype.brew = function(){
            console.log('用沸水冲泡咖啡');
          };
          CoffeeWithHook.prototype.pourInCup = function(){
            console.log('把咖啡倒进杯子');
          };
          CoffeeWithHook.prototype.addCondiments = function(){
            console.log('加糖和牛奶');
          };
          // 重写父类中的钩子函数
          CoffeeWithHook.prototype.customerWantsCondiments = function(){
            return window.confirm('咖啡中需要添加饮料吗?');
          };
 
          /*********创建子类Tea,继承父类,并且重写父类中的方法************/ 
          let TeaWithHook = function(){};
          // 通过原型链继承父类
          TeaWithHook.prototype = new Beverage();
          // 重写父类中的方法
          TeaWithHook.prototype.brew = function(){
            console.log('用沸水浸泡茶叶');
          };
          TeaWithHook.prototype.pourInCup = function(){
            console.log('把茶倒进杯子');
          };
          TeaWithHook.prototype.addCondiments = function(){
            console.log('加柠檬');
          };
           // 重写父类中的钩子函数
          TeaWithHook.prototype.customerWantsCondiments = function(){
            return window.confirm('茶中需要添加饮料吗?');
          };
          /******创建Tea和Coffee实例对象********/ 
          let coffee = new CoffeeWithHook(),
              tea = new TeaWithHook();
          coffee.init();
          tea.init();
 
      </script>
    </body>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值