简单工厂模式

简单工厂模式的设计是当我们需要各种各样的产品时,只需要在工厂新建一条产线,让工厂进行产品供给,而无需用户侧关心产品的制作细节,仅需要根据类型向工厂下订单即可。换到程序设计的语言,也即用户需要不同的产品类,这些产品类都具有相同功能、特性不同的接口,仅需要向工厂类提供类型,由工厂类进行分配,对工厂类而言,也不过是多了一个case去包含这个产品,实现了类间的松耦合。

简单工厂模式的角色为几类:

  • 抽象产品类:相当于提供给工厂统一接口,具体特性接口由产品自身override;

  • 具体产品类:提供不同的类特性和接口;

  • 唯一工厂类:工厂类负责生产各种各样的产品;

由描述可知C++ 虚函数多态可以完成实现,以下:

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>
using namespace std;

class Operation{ //抽象产品接口
public:
void setNum(int num1,int num2){
this->num1 = num1;
this->num2 = num2;
}

virtual int getResult() = 0;

virtual void clare(){}

virtual ~Operation(){}

protected:
int num1,num2;
};

//具体产品:加
class OperationAdd:public Operation{
public:
int getResult() override{
return this->num1 + this->num2;
}
void clare() override{
cout<<"Add Operation result:"<<getResult()<<endl;
}
};

//具体产品:减
class OperationSub:public Operation{
public:
int getResult() override{
return this->num1 - this->num2;
}
void clare() override{
cout<<"Sub Operation result:"<<getResult()<<endl;
}
};

enum class Operator:char{ //产品类型
Add,Sub
};

class OperationFactory{ //工厂类:返回产品对象
public:
Operation* getProduct(Operator op){
Operation* product = nullptr;
switch (op)
{
case Operator::Add:
product = new OperationAdd();
break;

case Operator::Sub:
product = new OperationSub();
break;
}
return product;
}
};

int main(){ //用户端
OperationFactory* factory = new OperationFactory(); //工厂实例

//产品订单
Operation* product = factory->getProduct(Operator::Add);
product->setNum(100,50);
product->clare();

delete factory;
delete product;

return 0;
}

工厂模式

上述模式因为使用了一个工厂去生产各种各样的商品,容易发现加入新产品的方式是多加一个case,要不停地改编这个工厂类,因此这里仍然存在耦合关系。如果将这个耦合关系再使用一次多态解耦出来,即一个抽象工厂+多个具体生产工厂,那么角色分配变成了一个抽象工厂+多个具体工厂+一个抽象产品类+多个具体产品类,此时这种模式就从简单工厂模式过渡到工厂模式,代码变化仅是工厂被抽象处理而已:

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
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
using namespace std;

class Operation{ //抽象产品接口
public:
void setNum(int num1,int num2){
this->num1 = num1;
this->num2 = num2;
}

virtual int getResult() = 0;

virtual void clare(){}

virtual ~Operation(){}

protected:
int num1,num2;
};

//具体产品:加
class OperationAdd:public Operation{
public:
int getResult() override{
return this->num1 + this->num2;
}
void clare() override{
cout<<"Add Operation result:"<<getResult()<<endl;
}
};

//具体产品:减
class OperationSub:public Operation{
public:
int getResult() override{
return this->num1 - this->num2;
}
void clare() override{
cout<<"Sub Operation result:"<<getResult()<<endl;
}
};

class OperationFactory{ //抽象工厂
public:
virtual ~OperationFactory(){}
virtual Operation* getProduct() = 0;
};

//具体生产加的工厂
class OperationFactory_Add:public OperationFactory{
public:
Operation* getProduct() override{
return new OperationAdd();
}
};

//具体生产减的工厂
class OperationFactory_Sub:public OperationFactory{
public:
Operation* getProduct() override{
return new OperationSub();
}
};

int main(){ //用户端
OperationFactory* factory = new OperationFactory_Sub(); //工厂实例

Operation* product = factory->getProduct();
product->setNum(100,50);
product->clare();

delete factory;
delete product;
return 0;
}

抽象工厂模式

简单工厂模式定义了工厂生成产品的模式,工厂模式将产品分发到具体的工厂进行生产,方便拓展产品。但是两种模式的产品都是一种类型的产品,因为我们在抽象产品类仅定义了一种接口,即Operation的setNum、getresult和clare,如果拓展多种抽象产品类,就是抽象工厂模式。

这里我们除了生产Operation,定义了完全不同的另外一种产品——Clothes,它们只需要在抽象工厂中定义独立的接口,同时,一个具体工厂不再对应一类产品,它可能对应一个产品系,例如同时生产Operation和Closthes,仅需一者时则返回一个空对象。

类似这种效果:

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
using namespace std;

class Operation{ //第一类抽象产品接口
public:
void setNum(int num1,int num2){
this->num1 = num1;
this->num2 = num2;
}

virtual int getResult() = 0;

virtual void clare(){}

virtual ~Operation(){}

protected:
int num1,num2;
};

//第一类具体产品:加
class OperationAdd:public Operation{
public:
int getResult() override{
return this->num1 + this->num2;
}
void clare() override{
cout<<"Add Operation result:"<<getResult()<<endl;
}
};

//第一类具体产品:减
class OperationSub:public Operation{
public:
int getResult() override{
return this->num1 - this->num2;
}
void clare() override{
cout<<"Sub Operation result:"<<getResult()<<endl;
}
};

class Clothes{
public:
void setMaterial(string material){
this->material = material;
}
virtual int getPrice() = 0;

protected:
string material;
int basePrice = 100;
};

class ClothesSilk :public Clothes{
public:
int getPrice() override{
return basePrice+100;
}
};

class ClothesCotton :public Clothes{
public:
int getPrice() override{
return basePrice+50;
}
};


class AbstractFactory{ //抽象工厂
public:
virtual Operation* getProduct_Operation() = 0;
virtual Clothes* getProduct_Clothes() = 0;
virtual ~AbstractFactory(){}
};

//具体A类生产工厂:加号+丝绸衣服
class ConcreateAFactory:public AbstractFactory{
public:
Operation* getProduct_Operation() override{
return new OperationAdd();
}

Clothes* getProduct_Clothes() override{
return new ClothesSilk();
}
};

//具体B类生产工厂:减号+棉衣服
class ConcreateBFactory:public AbstractFactory{
public:
Operation* getProduct_Operation() override{
return new OperationSub();
}

Clothes* getProduct_Clothes() override{
return new ClothesCotton();
}
};

int main(){ //用户端
AbstractFactory* aFactory = new ConcreateAFactory();
AbstractFactory* bFactory = new ConcreateBFactory();

Operation* add = aFactory->getProduct_Operation();
Clothes* silk = aFactory->getProduct_Clothes();
Operation* sub = bFactory->getProduct_Operation();
Clothes* cotton = bFactory->getProduct_Clothes();

add->setNum(100,50);
add->clare();

sub->setNum(100,50);
sub->clare();

cout<<silk->getPrice()<<endl;
cout<<cotton->getPrice()<<endl;

delete aFactory;
delete bFactory;
delete add;
delete silk;
delete sub;
delete cotton;

return 0;
}

参考链接:

  1. 第一章 简单工厂模式

  2. 简单工厂模式 - 人造恶魔果实工厂1

  3. 工厂模式 - 人造恶魔果实工厂2

  4. 设计模式之工厂模式(factory pattern)