江湖听闻,在JavaScript的中,往往一个复杂的架构或许库,抽丝剥茧后,大都是规划形式的使用。这次要介绍的模板办法形式由父类和子类构成,经过父类确认整个体系的履行流程,子类担任详细的流程完成,能够经过继承的办法重写父类的某些办法,但是不能改动功流程的履行顺序。表现了抽象与完成别离编程思维。

模板办法形式,父类封装流程,子类详细完成

图中,父类控制了整个体系的履行流程,子类担任详细的流程完成。

一、经典事例饮料冲制流程

咱们知道,冲制饮料一般有以下进程:
(1)把水煮沸
(2)用沸水冲泡饮料
(3)把饮料倒进杯子
(4)加调料
示例代码:

    // 父类:完成泡制饮料的子类功用的流程,本次功用有4个流程,如下:
    var Beverage = function () {}
    // 然后,咱们梳理冲制饮料的流程
    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 办法' );
    } 
    // 冲制饮料
    Beverage.prototype.init = function () {
        this.boilWater();
        this.brew();
        this.pourInCup();
        this.addCondiments();
    }
    // 子类:详细完成泡制一杯茶的的流程
    var Tea = function () {}
    Tea.prototype = new Beverage();
    Tea.prototype.brew = function () {
        console.log('用水泡茶');
    }
    Tea.prototype.pourInCup = function () {
        console.log('将茶倒进杯子');
    }
    Tea.prototype.addCondiments = function () {
        console.log('加冰糖');
    }
    var tea = new Tea();
    tea.init()

  从以上比如能够看出,父类现已拟定了泡制饮料的流程,并且确认了不管哪种饮料都需要把水煮沸的公共办法boilWater,至于brewpourInCupaddCondiments泡制茶、黑咖啡、牛奶和豆浆等饮料都有所不同,由子类去详细完成。

抽象的父类现已发生,接下来便是泡制茶的子类的详细完成,子类首要继承父类的泡制饮料的确认流程。其中,将水烧开继承父类,brewpourInCupaddCondiments办法由子类进行重写,至此,泡茶的流程现已完成,黑咖啡、牛奶和豆浆等饮料同理。

以上比如履行结果是:

模板办法形式,父类封装流程,子类详细完成

二.结构事例vue的主流程

  vue2.0是最受欢迎的前端结构之一,以其小而美的特点,成为众多前端小伙伴的首选。使用vue的进程中,大局办法的定义、生命周期的使用、组件的封装和路由的完成等都感觉模模糊糊都被一种力量牢牢锁定,vue各个功用在使用的进程有序进行着。翻看vue源码时才发现:

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'
import { warn } from '../util/index'
function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}
// Vue类由各种initMixin、stateMixin、eventsMixin、lifecycleMixin和renderMixin的办法有序的混入各种功用
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
export default Vue

咱们发现,Vue本质上是一个结构函数,在其new的时分,会履行内部仅有的初始化办法this._init

初始化办法在initMixin中完成:


  Vue.prototype._init = function (options?: Object) {
    const vm: Component = this
    // ...
    initLifecycle(vm)
    initEvents(vm)
    initRender(vm)
    callHook(vm, 'beforeCreate')
    initInjections(vm) // resolve injections before data/props
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
    // ...
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

能够看出,初始化this._init办法是由如图的一些办法确认有序履行的。vue的创立进程中的初始化办法this_init便是一种模板办法形式。

总结

  规划形式,百度百科的解说是对面向对象规划中重复出现的问题的处理方案。模板办法形式是众多规划形式之一,处理的主要事务场景是父类创立确认的子类功用或许使命的履行流程,子类继承的时分能够重写父类的某些办法。

参阅书籍《JavaScript规划形式与开发实践》(曾探)
参阅代码:cn.vuejs.org