架构师的工具-模板方法模式

jopen 8年前

所谓的模板就是一个重用一万次都不会觉得有问题的代码。 在es6中,提出了一个 ““”反引号的书写方式–又叫做模板字符串.他最大的功能就是用来书写模板html的.通常在js中使用模板是

  "There are <b>" + basket.count + "</b> " +    "items in your basket, " +    "<em>" + basket.onSale +    "</em> are on sale!"

像这样使用的在ES6中引入了模板字符串的概念,只需要使用反引号进行包裹就可以: 引入的变量可以使用${}进行包裹上面可以修改为:

`  //这里就是反引号,注意不是上引号,而是键盘esc下面那个键        There are <b>${basket.count}</b> items  //插入指定的变量         in your basket, <em>${basket.onSale}</em>        are on sale!   `

上面的代码就可以作为一串模板代码出现。同理,在js的设计模式中,也存在模板方法模式.

模板方法模式

模板方法模式是一种基于类和继承的模式。也是一些架构师常用的模式。

看个栗子: 小明起床

首先,小明起床,喜欢穿NB系列衣服,然后洗脸刷牙,整理书包,出门。(我这里列的是大部分人有的,如果遇见一些生活习惯不同的,那先将就下吧。:)

转换为代码:

var GetUp = function(){}  GetUp.prototype.wear = function(){      console.log("穿NB系列的衣服");  }  GetUp.prototype.brush = function(){      console.log("洗脸刷牙");  }  GetUp.prototype.sortOut = function(){      console.log("整理书包");  }  GetUp.prototype.out = function(){      console.log("出门");  }  GetUp.prototype.init = function(){      this.wear();      this.brush();      this.sortOut();      this.out();  }  var xiaoming = new GetUp();  xiaoming.init();

看上去,可以完美的表达小明的起床过程,但是我们是有情怀的人。我们想做的是,能不能抽象出一个大部分人都能用的起床模式. 有,我们可以想想。

我是一个穷逼,我家只能穿阿迪吊丝的衣服,

我现在正在找工作,我需要整理文件。

然后,洗脸刷牙这个习惯还是有的。

出门是必须的。

那么对比可以看出,只有两个方法的内容不一样,只需要对这两个方法进行抽象. 相当于写一个抽象方法,然后让子类自己重写。

var GetUp = function(){}  GetUp.prototype.wear = function(){   //写出方法,需要子类自己定义      throw "穿衣服需要子类自定义";  }  GetUp.prototype.brush = function(){      console.log("洗脸刷牙");  }  GetUp.prototype.sortOut = function(){  //子类自定义方法      throw "出门准备工作需要子类自定义";  }  GetUp.prototype.out = function(){      console.log("出门");  }  GetUp.prototype.init = function(){      this.wear();      this.brush();      this.sortOut();      this.out();  }  var xiaoMing = new GetUp();  xiaoMing.wear = function(){      console.log("穿阿迪吊丝的衣服");  }  xiaoMing.sortOut = function(){      console.log("整理文件,找工作");  }  xiaoMing.init();

恩,这个模板,差不多能满足正常人的需求。 但是,世界只有相对性,而没有绝对性,某些有怪癖,比如,早上不洗脸刷牙.这种情况也是存在的。(我小时候,为了逃避刷牙,经常起得比我妈还早,就跑去上课). md, 怪不得我那时候同座都嫌弃我,哎,也没有找到小时候的知己。现在肠子都悔青了。回正题。所以,要满足这类人的需求,我们要用到一个叫做钩子方法。其实就是一个flag.用来代表你是不是比较特殊的人。

var GetUp = function(){}  GetUp.prototype.wear = function(){   //写出方法,需要子类自己定义      throw "穿衣服需要子类自定义";  }  GetUp.prototype.brush = function(){      console.log("洗脸刷牙");  }  GetUp.prototype.sortOut = function(){  //子类自定义方法      throw "出门准备工作需要子类自定义";  }  GetUp.prototype.out = function(){      console.log("出门");  }  GetUp.prototype.needBrush = function(){  //是否需要刷牙,默认为需要      return  true;    }  GetUp.prototype.init = function(){      this.wear();      if(this.needBrush())this.brush();      this.sortOut();      this.out();  }  var xiaoMing = new GetUp();  xiaoMing.wear = function(){      console.log("穿阿迪吊丝的衣服");  }  xiaoMing.sortOut = function(){      console.log("整理文件,找工作");  }  xiaoMing.needBrush = function(){return false;}  xiaoMing.init();

上面自定义的 “needBrush” 方法就是一个钩子方法,用来表明,这个人是不是特立独行的人。

其实,我们抛开钩子的写法,了解下他的本质,我们可以发现,一个钩子的添加,是给你抽象类的重用性大大加分的一项,将变化的一部分,给分离出来,更大程度的让代码得到重用.

但是,在js中写类,有点太过牵强。要知道js中,函数,对象才是一等公民.我们可以使用高阶函数重构一个例子.

var GetUp = function(person){      var wear = person.wear || function(){          throw "穿衣服需要子类自定义";      }         var brush = function(){          console.log("洗脸刷牙");      }      var sortOut = person.sortOut || function(){          throw "出门准备工作需要子类自定义";      }      var needBrush = person.needBrush || function(){          return true;      }      var out = function(){          console.log("出门");      }      var init = function(){          wear();          if(needBrush()) brush();          sortOut();          out();      }      return  function(){          init();      }  }  var jimmy = {      wear(){          console.log("穿鸟不拉屎的衣服");      },      sortOut(){          console.log('整理书包');      }  }  var _jimmy = GetUp(jimmy);  _jimmy();

但是为了统一,可以将init方法返回.

var GetUp = function(person){      //...      return {          init      }  }  var _jimmy = GetUp(jimmy);  _jimmy.init();

这样写,更具有代表性,让人能够一眼看出来表示的意思.

模板方法的应用

模板方法的应用,其实往大的用,是给架构师来使用。比如他设计一个模板,然后交给底层程序员去实现。相当于,一个产经提一个需求,然后交给你来实现具体的内容(这两者的区别就是,一个可以忽悠,另一个不能忽悠).

往小的用,那就不叫模板了,就是普通的策略者模式了。

说了这么多,其实,废话+n. 模板方法在我们这个level 其实用的还是比较少了。当然也不排除,你对这个模板方法有着SM的爱好,天天套它。所以,还是一句话,不要为了模式而模式。看自己心情使用吧.

ending~

</div>

来自: http://hao.jser.com/archive/9146/