一、模式概述
从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现,学习了此模式可以为后面的很多中模式打下基础。那好,我们就来了解下什么是简单工厂模式?
我们来分析一个现实生活中的案例,每天早晨起床洗唰后是干什么呢?吃早餐(这里只针对在外吃早餐的上班族)、坐车(我是穷人只有坐公交,当然很多有钱人都自己有车,这里不考虑这些)去公司上班、是这样的吗?OK,下面就来分析下吃早餐中的故事,大家先看看下面这个图:
当我们在买早餐的时候,早餐店里都卖得写什么呢?这点你有注意吗?众多食品摆在那里,你只对营业员说你要何种食品,他便会知道给你拿什么样的食品给你,这说明什么呢?
如果用面向对象的思想来理解的话,营业员在这里就充当了一个工厂的角色,他负责根据你的请求返回你需要的食品对象。而这一点正是简单工厂模式的意图。
二、模式意图
简单工厂模式根据提供给他的数据,返回几个可能类中的一个类的实例。
三、模式UML图
下面是简单工厂模式的示意性UML图:
如上图,简单工厂模式UML我画了两种,详细如下:
① 只有一个产品对象的简单工厂模式。
② 带有一个抽象产品对象的简单工厂模式。
四、模式参与者
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象。
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
抽象产品(AbstractProduct)角色: 是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
具体产品(ConcreteProduct)对象:工厂模式所创建的对象都是这个角色的实例。
五、场景:实现两个数的加减乘除
运算父类:实现了操作运算的公有属性和方法,包括,两个操作数,获得结果方法。
get_result()必须是抽像方法,这样,子类赋给父类对象时,仍是调用子类的方法。
4 class Operator
5 {
6 public:
7 Operator()
8 : A(0.0), B(0.0)
9 {
10 }
11
12 Operator(double a, double b)
13 {
14 A = a;
15 B = b;
16 }
17
18 virtual double get_result() // 必须实现为虚函数
19 {
20 return 0.0;
21 }
22
23 void setA(double a)
24 {
25 A = a;
26 }
27 void setB(double b)
28 {
29 B = b;
30 }
31
32 protected:
33 double A;
34 double B;
35 };
加减乘除的子类:继承自父类,实际了父类的虚函数get_result()。
37 class Add : public Operator
38 {
39 public:
40 Add()
41 : Operator()
42 {
43 }
44
45 Add(double a, double b)
46 : Operator(a, b)
47 {
48 }
49
50 double get_result()
51 {
52 return A+B;
53 }
54 };
55
56 class Reduce : public Operator
57 {
58 public:
59 Reduce()
60 : Operator()
61 {
62 }
63
64 Reduce(double a, double b)
65 : Operator(a, b)
66 {
67 }
68
69 double get_result()
70 {
71 return A-B;
72 }
73 };
简单工作厂类:用于生成运算对象
118 class OperatorFactory
119 {
120 public:
121 static Operator* createOperator(char o)
122 {
123 Operator *oper;
124 switch(o)
125 {
126 case '+':
127 oper = new Add();
128 break;
129 case '-':
130 oper = new Devide();
131 break;
132 case '*':
133 oper = new Multiply();
134 break;
135 case '/':
136 oper = new Devide();
137 break;
138 }
139 return oper;
140 }
141
142 };
使用:
1 #include <iostream>
2 #include <stdlib.h>
3 #include <stdexcept>
4 #include <unistd.h>
5 #include "opt.h"
6
7 int main(int argc, char* argv[])
8 {
9 if(argc != 4)
10 {
11 std::cout << "Please input three operators" << std::endl;
12 std::cout << "Usage: a.out 1 + 2" << std::endl;
13 exit(0);
14 }
15
16 double a = atof( argv[1]);
17 char o = argv[2][0];
18 std::cout << "o = " << o << std::endl;
19 double b = atof( argv[3]);
20
21 OperatorFactory f;
22 Operator *op = f.createOperator(o);
23 op->setA(a);
24 op->setB(b);
25 std::cout << op->get_result() << std::endl;
26 delete op;
27 exit(0);
28 }
六、模式优缺点
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
![](https://i-blog.csdnimg.cn/blog_migrate/ef196e53a221a66e9459aa337f6d6a31.jpeg)
系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了
"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。