# 一. 描述

  1. 创建型模式对类的实例化过程进行了抽象,能够将对象的创建与对象的使用过程分离。
  2. 定义:简单工厂模式又称为静态工厂方法模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
  3. 角色:简单工厂模式包含三个角色:工厂角色负责实现创建所有实例的内部逻辑;抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口;具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例。
  4. 简单工厂模式的要点在于:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
  5. 简单工厂模式最大的优点在于实现对象的创建和对象的使用分离,将对象的创建交给专门的工厂类负责,但是其最大的缺点在于工厂类不够灵活,增加新的具体产品需要修改工厂类的判断逻辑代码,而且产品较多时,工厂方法代码将会非常复杂。
  6. 简单工厂模式适用情况包括:工厂类负责创建的对象比较少;客户端只知道传入工厂类的参数,对于如何创建对象不关心。

# 二. 实例

  1. 简单例子
function createPerson(name) {
  var o = {};
  o.name = name;
  o.getName = function() {
    console.log(this.name);
  };
  return o;
}
var p1 = createPerson("张三");
p1.getName();
1
2
3
4
5
6
7
8
9
10
  1. 复杂例子
function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() {
  console.log(this.name);
};
function Car(model) {
  this.model = model;
}
Car.prototype.getModel = function() {
  console.log(this.model);
};
function Create(type, param) {
  // return new this[type](param)
  // 不写new的话,在这里new一个
  if (this instanceof Create) {
    // instanceof会判断后面的构造函数的原型,是不是存在在前面这个对象的原型链里
    return new this[type](param);
  } else {
    return new Create(type, param);
  }
}
Create.prototype = {
  person: Person,
  car: Car,
};
var p1 = new Create("person", "张三");
// 如果不写 new 的话,就在工厂函数里面去 new,写了 new,就直接调用
var c1 = Create("car", "奔驰");
p1.getName();
c1.getModel();
/*
   new Create('person', '张三') --> {
        __proto__: Create.prototype
   } 
   new this[type](param) --> new Person('张三') --> {
        __proto__: Persopn.prototype,
        name: '张三'
   }
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  1. 例子
"use strict";

// 篮球基类
var BasketBall = function() {
  this.intro = "篮球盛行于美国";
};

BasketBall.prototype = {
  getMember: function() {
    console.log("每个队伍需要5名队员");
  },

  getBallSize: function() {
    console.log("篮球很大");
  },
};

// 足球基类
var FootBall = function() {
  this.intro = "足球在世界范围内很流行";
};

FootBall.prototype = {
  getMember: function() {
    console.log("每个队伍需要11名队员");
  },

  getBallSize: function() {
    console.log("足球很大");
  },
};

// 网球基类
var Tennis = function() {
  this.intro = "每年有很多网球系列赛";
};

Tennis.prototype = {
  getMember: function() {
    console.log("每个队伍需要1名队员");
  },

  getBallSize: function() {
    console.log("网球很小");
  },
};

// 运动工厂
var SportsFactory = function(name) {
  switch (name) {
    case "NBA":
      return new BasketBall();
    case "wordCup":
      return new FootBall();
    case "FrenchOpen":
      return new Tennis();
  }
};

// 为NBA杯创建一个篮球,只需要记住运动工厂 SportsFactory,调用并创建
var NBA = SportsFactory("NBA");
console.log(NBA);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  1. 例子
"use strict";

function createBook(name, time, type) {
  var o = {
    name: name,
    time: time,
    type: type,
    getName: function() {
      return this.name;
    },
  };

  return o;
}

var book1 = createBook("javascript", "2015", "js");
var book2 = createBook("Nodejs", "2015", "Nodejs");

console.log(book2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19