DesignPattern 2 工厂模式

工厂顾名思义就是创建产品,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,属于创建型模式,其中简单工厂模式不属于GOF23设计模式中。

二、Factory 工厂模式

  • 定义:

    工厂模式(Factory Pattern):在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

  • 场景:

  1. 不想让某个子系统与较大的那个对象之间形成强耦合,而是想运行时从许多子系统中进行挑选;
  2. 将new操作简单封装
  3. 需要依赖具体环境创建不同实例,这些实例都有相同的行为
  4. 抽象工厂模式一般用于严格要求以面向对象思想进行开发的超大型项目中

1. 简单工厂模式

简单工厂模式并没有列入到GOF23设计模式中,原因为太简单了,而且违反了开闭原则。

  • 特点

    定义一个创建对象的接口,由工厂类进行实例化,统一管理。

  • 应用场景

    工厂类负责创建的对象比较少;客户端(应用层)只需要知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。

  • 优点

    统一管理, 简单易用

  • 缺点

    新增类的情况只能去修改代码,违反开闭原则,增加系统复杂度

  • 实例

    小米、华为、苹果三个品牌的手机都是在同一个工厂里生产的,且都是同一时间进行生产,那么工厂就可以决定生产哪个品牌的手机了
  • UML 类图

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
// 手机类
class MobilePhone {
public:
virtual void description() = 0; // 纯虚函数
};

// 小米手机类
class Miui : public MobilePhone {
public:
void description() { // 描述信息
cout << "小米手机" << endl;
}
};

// 华为手机类
class Huawei : public MobilePhone {
public:
void description() {
cout << "华为手机" << endl;
}
};

// 苹果手机类
class Iphone : public MobilePhone {
public:
void description() {
cout << "苹果手机" << endl;
}
};
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
// 手机生产工厂
class Factory {
public:
// 根据传入来的类型,进行对应的分配对象返回
MobilePhone *manufacturePhone(PHONE_TYPE type) {
switch (type) {
case MIUI:
return (new Miui());
break;
case HUAWEI:
return (new Huawei());
break;
case IPHONE:
return (new Iphone());
break;
default:
return NULL;
break;
}
}
};

void test()
{
// 建立工厂对象
unique_ptr<Factory> factory(new Factory);

// 工厂对象调用manufacturePhone方法给父类指针对象分配对象
unique_ptr<MobilePhone> xiaoMi(factory->manufacturePhone(MIUI));
xiaoMi->description();
unique_ptr<MobilePhone> huaWei(factory->manufacturePhone(HUAWEI));
unique_ptr<MobilePhone> iphone(factory->manufacturePhone(IPHONE));
}

2. 工厂模式

  • 特点

    定义一个创建对象的接口,由工厂类的派生类进行实例化。

  • 场景

    创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口;客户不关心创建产品的细节,只关心产品的品牌。

  • 优点

    解决了简单工厂的缺点

  • 缺点

    类的个数容易过多;每新增一个新产品时就需要增加两个类,导致系统的复杂度增加,不好维护;

  • 实例

    不再只是由一个手机生产的工厂生产手机了,而是每种品牌都有自己的生产工厂,每个品牌的手机生产不会影响到其他手机生产线;增删手机品牌不需要去修改其他手机厂商的代码,符合开闭原则。

  • UML 类图

基于简单工厂实例代码,调整工厂方法如下

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
// 手机生产工厂
class Factory {
public:
virtual MobilePhone *manufacturePhone() = 0; // 纯虚函数
};

// 小米手机生产工厂
class MiuiFactory : public Factory {
public:
MobilePhone *manufacturePhone() {
return (new Miui());
}
};

// 华为手机生产工厂
class HuaweiFactory : public Factory {
public:
MobilePhone* manufacturePhone() {
return (new Huawei());
}
};

// 苹果手机生产工厂
class IphoneFactory : public Factory {
public:
MobilePhone* manufacturePhone() {
return (new Iphone());
}
};

void test()
{
// 定义工厂指针对象
unique_ptr<Factory> factory(new MiuiFactory);
// 工厂对象调用manufacturePhone方法给父类指针对象分配对象
unique_ptr<MobilePhone> xiaoMi(factory->manufacturePhone());
xiaoMi->description();

// 从新给工厂对象分配对象
unique_ptr<Factory> factory2(new HuaweiFactory());
unique_ptr<MobilePhone> huaWei(factory->manufacturePhone());
huaWei->description();
}

三、抽象工厂

抽象工厂模式是工厂方法模式的升级版,不再是局限于生产一种类型的生产工厂。

  • 特点

    为创建一组(有多类)相关或依赖的对象提供创建接口

  • 场景

  1. 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、洗衣机、空调等。
  2. 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
  • 优点

    解决了工厂模式的缺点,将一个系列的产品族统一到一起创建。

  • 缺点

  1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口;
  2. 增加了系统的抽象性和理解难度。
  3. 当系统中只存在一个等级结构的产品时,抽象工厂模式将退化到工厂方法模式。
  4. 当增加一个新的产品族时只需增加一个新的具体工厂,不需要修改原代码,满足开闭原则;当产品族中需要增加一个新种类的产品时,则所有的工厂类都需要进行修改,不满足开闭原则。
  • 实例

    以上面的手机工厂为基础,在拓展出一个升级版的手机生产工厂,手机二代。

  • UML 类图

基于工厂模式代码,新增升级版手机类,调整如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 升级版手机类
class NewMobilePhone {
public:
virtual void newDescription() = 0;
};

// 升级版小米手机类
class NewMiui : public NewMobilePhone {
public:
void newDescription() {
cout << "小米手机二代" << endl;
}
};

// 升级版华为手机类
class NewHuawei : public NewMobilePhone {
public:
void newDescription() {
cout << "华为手机二代" << endl;
}
};
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
// 手机生产工厂
class Factory {
public:
virtual MobilePhone *manufacturePhone() = 0; // 纯虚函数

virtual NewMobilePhone *newManufacturePhone() = 0; // 纯虚函数
};

// 小米手机生产工厂
class MiuiFactory : public Factory {
public:
// 生产小米手机(生成小米手机对象返回)
MobilePhone *manufacturePhone() {
return (new Miui());
}

// 生产升级版小米手机(生成小米手机二代对象返回)
NewMobilePhone *newManufacturePhone() {
return (new NewMiui());
}
};

// 华为手机生产工厂
class HuaweiFactory : public Factory {
public:
// 生产华为手机(生成华为手机对象返回)
MobilePhone *manufacturePhone() {
return (new Huawei());
}

// 生产升级版华为手机(生成华为手机二代对象返回)
NewMobilePhone *newManufacturePhone() {
return (new NewHuawei());
}
};

void test()
{
// 定义工厂指针对象
unique_ptr<Factory> factory(new MiuiFactory);
// 生产小米手机
unique_ptr<MobilePhone> xiaoMi(factory->manufacturePhone());
xiaoMi->description();
// 生产小米手机二代
unique_ptr<NewMobilePhone> xiaoMi(factory->newManufacturePhone());
newXiaoMi->newDescription();
}