简单工厂

有一个函数能够创建对象,并且这个函数用的是(),而不是通过new得来的,此时这个函数就是工厂函数;

工厂模式是对象的创建模式之一,和传统new创建对象相比;工厂模式使用的是工厂函数来创建对象的。

下面的代码就是简单的工厂的创建

 1  <script>
 2       function createPerson(name, age, sex) {
 3     return {
 4         name: name,
 5         age: age,
 6         sex: sex,
 7         sayHello: function() {
 8             console.log("你好我是" + this.name + "今年" + this.age + "岁了,我是一个" + this.sex)
 9         }
10     }
11 };
12 var xiaoming = createPerson("小明", 12, '男生');
13 var xiaohong = createPerson("小红", 13, "女生")
14 console.log(xiaoming)
15 console.log(xiaohong)
16     </script>

★工厂模式★_创建对象

 

 

此时会发现一个问题,上面的工厂模式不能使用instanceof,因为对象是通过圆括号直接执行的

1 var xiaoming = new createPerson("小明", 12, '男生');
2 var xiaohong = createPerson("小红", 13, "女生")
3 console.log(xiaoming instanceof createPerson)
4 console.log(xiaohong instanceof createPerson)

此时我们会发现都为false

★工厂模式★_构造函数_02

 

 

我们来看下面工厂函数的基本雏形

 1     <script>
 2     function Car(color, doors) {
 3     this.color = color;
 4     this.doors = doors;
 5 }
 6 Car.prototype.hello = function() {
 7     console.log("你好,我是小汽车,我的颜色是" + this.color + "色,一共有" + this.doors + "个门");
 8 };
 9 // 工厂类型
10 function createVihicle(color, doors) {
11     return new Car(color, doors);
12 }
13 var car1 = new createVihicle("红", 2)
14 var car2 = new createVihicle("黑", 4)
15 console.log(car1)
16 console.log(car2)
17 console.log(car1 instanceof Car)
18 console.log(car2 instanceof Car)
19     </script>

★工厂模式★_创建对象_03

 

 

此时我们有难免有一个疑问,为什么要多次一举?不直接new Car呢?

我们说工厂模式实际上就是一种思维方式的转变,它的本质是面向接口编程。

构造函数使用的是new操作符,通过new实现的结果我们称之为“针对实现编程”

 

普通工厂

 1     <script>
 2    // 小汽车
 3 function Car(color, doors) {
 4     this.color = color;
 5     this.doors = doors;
 6     // 这个地方要return,因为工厂类里面使用的是car执行,不是new,所以不会自动return
 7     return this;
 8 }
 9 // 大卡车
10 function Trank(weight) {
11     this.weight = weight;
12     return this;
13 }
14 // 工厂类型
15 function createVihicle(type) {
16     // 通过type进行判断,如果是Car则表示创建小汽车,如果Trank则表示创建大卡车
17     if (type == "Car") {
18         // apply的作用是执行函数的上下文
19         return Car.apply(new Car(), [].slice.call(arguments, 1))
20     } else if (type == 'Trank') {
21         return Trank.apply(new Trank(), [].slice.call(arguments, 1))
22     }
23 }
24 
25 var xiaoqiche = new createVihicle("Car", "red", 4);
26 var dakache = new createVihicle("Trank", 500)
27 console.log(xiaoqiche)
28 console.log(dakache)
29 console.log(xiaoqiche instanceof Car)
30 console.log(dakache instanceof Trank)
31     </script>

★工厂模式★_构造函数_04

 

 

抽象工厂

抽象工厂就是提供一个注册方法,然后实例这个类。
工厂维护一个类的清单,我们用一个对象来维持当前的所有的类内容,注册的时候可以提供预审查功能。比如我们要求所有的注册类都必须要有update和render方法,否则不允许注册

 1     <script>
 2 function Duck(color, age) {
 3     this.color = color;
 4     this.age = age;
 5     return this;
 6 }
 7 Duck.prototype.update = function() {}
 8 Duck.prototype.render = function() {}
 9 function Chicken(color,age) {
10     this.color = color;
11     this.age = age;
12     return this;
13 }
14 Chicken.prototype.update = function() {};
15 Chicken.prototype.render = function() {};
16 // 定义一个工厂
17 var Factory = (function() {
18     // 存储的是类型,不同的角色
19     var types = {};
20     return {
21         registFactory: function(type, typeFunction) {
22             // 预审查
23             if (!typeFunction.prototype.update || !typeFunction.prototype.render) {
24                 throw new Error(type + "类型没有注册成功,请设置update和render方法后再次进行注册")
25                 return;
26             }
27             // 给types对象注册方法
28             types[type] = typeFunction;
29         },
30         // 生成演员
31         careateActor: function(type) {
32             return types[type].apply(new types[type](), [].slice.call(arguments, 1));
33         }
34     }
35 
36 })();
37 // 注册
38 Factory.registFactory("Duck", Duck);
39 Factory.registFactory("Chicken", Chicken);
40 // 实例,必须要先注册才能进行实例
41 var yazi = Factory.careateActor("Duck", "黄", 1)
42 var xiaoji = Factory.careateActor("Chicken", "红",2)
43 console.log(yazi)
44 console.log(xiaoji)
45     </script>

★工厂模式★_抽象工厂_05