js模版方法模式

模版方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。在模版方法模式中,子类实现中的逻辑相同部分被上移到父类中,而将不同的部分留待子类来实现。适用场景为2个或多个有相似逻辑的对象,详细demo可以参考我github上的template.js

coffee and tea

咖啡与茶是一个经典的例子,泡咖啡的步骤如下

   var Coffee = function(){};
   Coffee.prototype = {
       boilWater: function(){
           console.log('把水煮沸');
       },
       brewCoffeeGriends: function(){
           console.log('用沸水泡咖啡');
       },
       pourInCup: function(){
           console.log('把咖啡倒进杯子里');
       },
       addSugarAndMilk: function(){
           console.log('加糖和牛奶');
       }
   }
   Coffee.prototype.init = function(){
       this.boilWater();
       this.brewCoffeeGriends();
       this.pourInCup();
       this.addSugarAndMilk();
   }
   var coffee = new Coffee();
   coffee.init();

泡一壶茶的步骤如下:

   var Tea = function(){};
   Tea.prototype = {
       boilWater: function(){
           console.log('把水煮沸');
       },
       steepTeaBag: function(){
           console.log('用沸水泡茶叶');
       },
       pourInCup: function(){
           console.log('把茶叶倒进杯子里');
       },
       addLemon: function(){
           console.log('加柠檬');
       }
   }
   Tea.prototype.init = function(){
       this.boilWater();
       this.steepTeaBag();
       this.pourInCup();
       this.addLemon();
   }
   var tea = new Tea();
   tea.init();   

抽离相同逻辑

我们可以发现泡咖啡和泡茶主要由以下不同点

  • 原料不同。一个是咖啡,一个是茶,但我们可以把它们都抽象为饮料。
  • 泡的方式不同,咖啡是冲泡,茶叶是浸泡,我们可以把它们都抽象为泡。
  • 加入的调料不同,一个是糖和牛奶,一个柠檬,但我们可以把他们都抽象为调料。

所以我们抽象出这样一个逻辑:1. 把水煮沸 2. 用沸水冲泡饮料 3. 把饮料倒进杯子 4. 加调料。
不管是冲泡还是浸泡,我们都抽象为一个新的方法,比如说brew

   var Beverage = function(){};
   Beverage.prototype = {
       init: function(){
           this.boilWater();
           this.brew();
           this.pourInCup();
           this.addCondiments();
       },
       //相同的,不需要被重写的方法直接定义实现
       boilWater: function(){
           console.log('把水煮沸');
       },
       //空方法,由子类重写,相当于java的抽象类
       brew: function(){
       },
       pourInCup: function(){
       },
       addCondiments: function(){
       }
   }

接下来就非常简单了

   var Coffee = function(){};
   Coffee.prototype = new Beverage();
   Coffee.prototype.brew = function(){
       //开始具体定义...
   }
   var coffee = new Coffee();
   coffee.init();
   //茶叶也一样

在上面的例子中,Beverage.prototype.init方法就是我们的模版方法,该方法封装了子类的算法框架,它作为一个算法的模版,指导子类以何种顺序去执行哪些方法

钩子方法

如果我们上述的步骤有一些额外的操作,想加入一些回调怎么办?钩子(hook)方法可以用来解决问题,放置钩子是隔离变化的一种常见手段,我们在父类中容易变化的地方放置钩子。

   Beverage.prototype.init = function(){
       this.boilWater();
       this.brew();
       this.pourInCup();
       if(this.customerWantsCondiments()){
           this.addCondiments();
       }
   }
   //在子类中
   Coffee.prototype.customerWantsCondiments(){
       return window.confirm('请问需要调料吗');
   }

在实际开发中,有时候需要给一些公用的ajax方法中传入回调,这时候回调也可以写成公用的钩子形式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值