2019-10-10 | 随笔杂记 | UNLOCK | 更新时间:2019-10-10 14:20

模板方法模式和面向对象

需要了解的几个概念

构造函数:构造函数其实就是普通的函数,只不过有以下的特点:首字母大写,内部使用this,使用new生成实例
面向对象:面向对象和面向过程都是一种思想,他们的区别在于,一个以过程为主,一个以对象为主
封装:类其实就是保存了一个函数的变量,这个函数有自己的属性和方法。将属性和方法组成一个类的过程就是封装
继承:子类可以使用父类的所有功能,并且对这些功能进行扩展。继承的过程,就是从一般到特殊的过程
多态:一个引用类型(变量)在不同情况下的多种状态。多态用途在于做面向对象开发时,方法不变,参数改变。

模板方法模式和原型对象

var Cat = function(){}              // 声明构造函数

Cat.prototype.call=function(){      // 设置原型方法
    console.log('喵喵喵')
}
Cat.prototype.eat=function(){
    console.log('猫吃了一条鱼')
}

Cat.prototype.init=function(){
    this.call()
    this.eat()
}

let xiaohei=new Cat()
xiaohei.init()

模板方法,原型链和继承

// 父类构造函数
var Animal=function(){}              // 声明构造函数
Animal.prototype.call=function(){    // 设置原型方法
    throw this+'需要重写 call 方法'
}
Animal.prototype.eat=function(){
    throw this+'需要重写 eat 方法'
}
Animal.prototype.iseat=function(){   // 通过子类的复写决定父类的执行
    return false
}
Animal.prototype.init=function(){
    this.call()
    if(this.iseat){
      this.eat()
    }
}

// 子类构造函数
var Cat = function(){}
Cat.prototype = new Animal()         // 将原型指向父类实例来继承父类

Cat.prototype.call=function(){
    console.log('喵喵喵')
}
Cat.prototype.eat=function(){
    console.log('猫吃了一条鱼')
}

let xiaohei=new Cat()
xiaohei.init()

模板方法模式的应用场景

模板模式,顾名思义,就是通过模板拓印的方式。通过抽象类来定义一个逻辑模板,逻辑框架、逻辑原型,然后将无法决定的部分抽象成抽象类交由子类来实现,一般这些抽象类的调用逻辑还是在抽象类中完成的。

  • 优点是父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
  • 缺点是需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象

适用场景:

  • 对一些复杂的算法进行分割,将其算法中固定不变的部分设计为模板方法和父类具体方法,而一些可以改变的细节由其子类来实现。

  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。

  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。