11

前言

设计模式填坑系列,紧接前文(距离上次写笔记又过去了一个多月,我也不知道怎么加班加着加着就一个月了-_-!)

正文

定义

工厂模式是指提供一个创建对象的接口而不保留具体的创建逻辑,可以根据输入类型创建对象。让子类自行决定实例化哪一种工厂类,实际的创建对象过程在子类中进行。在创建相似子类的时候,执行重复操作。(觉得我说的太抽象没关系,马上就到举例子环节)

具体实现

前面的描述可能还是稍显抽象,举个游戏里面的例子,我们需要实现一个生产游戏角色的RoleMaker工厂,达到以下目的:

var warrior = RoleMaker.factory('warrior')//生产一个战士
var mage = RoleMaker.factory('mage')//生产一个法师
var priest = RoleMaker.factory('priest')//生产一个牧师
warrior.introduce()// 输出 '我是一个战士,我的特长是近战'
mage.introduce()// 输出 '我是一个法师,我的特长是魔法'
priest.introduce()// 输出 '我是一个牧师,我的特长是治疗'

在这里,我们可以看到形如var warrior = RoleMaker.factory('warrior')的语句,就是使用RoleMaker工厂生产了一个战士的过程,这里的战士法师牧师都是角色的一个子类。

接下来就是如何实现上面的RoleMaker类,最核心的思想还是原型链继承(忘记的同学请自行补课,磨刀不误砍柴工),具体的实现代码如下:

  //父类
  function RoleMaker() {
    // 这里是父类的属性
  }

  RoleMaker.prototype.introduce = function () {
    return '我是一个' + this.type + ',我的特长是' + this.specialty
  }

  //工厂方法
  RoleMaker.factory = function (type) {
    var role;
    // 这里我们直接把子类构造函数都保存在父类的静态属性中,这样的好处是不污染全局命名空间,同时方便查找。实际上当然也可以直接用`switch-case`实现
    if (typeof (RoleMaker[type]) !== "function") {
      //对未指定子类的处理,这里是直接抛出错误,也可以为未指定类型做默认值处理
      throw {
        name: 'Error',
        message: type + 'does not exist'
      }
    }
    if (typeof (RoleMaker[type].prototype.introduce !== "function")) {
      // 判断是否已经实现继承,注意只继承一次,当然由于只是原型链继承这里判断条件也可以用`RoleMaker[type].constructor===RoleMaker`
      RoleMaker[type].prototype = new RoleMaker()
    }

    role = new RoleMaker[type]() //实例化,也就是实际创建对象的过程
    return role
  }

  // 每个子类的构造函数
  RoleMaker.warrior = function () {
    this.type = "战士",
      this.specialty = "近战"
  }
  RoleMaker.mage = function () {
    this.type = "法师",
      this.specialty = "魔法"
  }
  RoleMaker.priest = function () {
    this.type = "牧师",
      this.specialty = "治疗"
  }

以上代码比较简单,来回顾下前文说道的几个特点:

  1. 使用者只需要知道特定子类的名称就可以直接生产对应的子类,无需知道具体实现逻辑
  2. 实际的创建对象过程在子类中进行
  3. 在创建相似子类的时候,执行重复操作(每个子类只做一次的继承)

补充一个实例

实际上,js的Object()函数,就很符合工厂模式的特征:

var n = Object(1)
n.constructor === Number
var s = Object('1')
n.constructor === String
var b = Object(true)
n.constructor === Boolean

小结

自我感觉设计模式系列由于还是处于学习阶段,实践经验相对较少,所以写起来还是偏向于读书笔记类,所以可能有很多地方都显得粗糙。权当做先占个坑,等后续有更深入理解再回来补上。
然后惯例感谢之前的热心读者,尤其是为我指出错误的小伙伴。
然后依然是每次都一样的结尾,如果内容有错误的地方欢迎指出;如果对你有帮助,欢迎点赞和收藏,转载请征得同意后著明出处,如果有问题也欢迎私信交流,主页添加了邮箱地址~溜了


安歌
7k 声望5.5k 粉丝

目前就职于Ringcentral厦门,随缘答题, 佛系写文章,欢迎私信探讨.