【C++设计模式】抽象工厂模式
学习总结
(1)抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品。
- 抽象工厂模式的优点:
- 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
- 新加入产品系列时,无需修改原有系统,增强了系统的可扩展性,符合开闭原则。
- 抽象工厂模式的缺点:
- 在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则
- 适用环境:
- 一系列/一族产品需要被同时使用时,适合使用抽象工厂模式;
- 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品
抽象工厂模式中,如果需要新增加一个系列的产品,比如足球系列,只需增加一族新的具体产品类(抽象和具体)并提供一个对应的工厂类即可。但是,如果要在已有的产品族里增加另一个产品,比如Jungle打篮球,除了需要篮球和篮球衣外,Jungle还想换双篮球鞋,这时候该怎么办呢?是不是要去修改BasketballFactory呢?
一、抽象工厂模式
抽象工厂模式,其抽象程度更高,每一个具体工厂可以生产一组相关的具体产品对象。
抽象工厂模式的定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
1.1 抽象工厂模式结构
抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品:
- 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
- 具体工厂(ConcreteFactory):生产具体的产品
- 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
- 具体产品(ConcreteProduct):具体的产品类
结合抽象工厂模式定义和UML,可以看到具体工厂ConcreteFactory_A
可以生产两种产品,分别是ConcreteProduct_A_1
和ConcreteProduct_A_2
,另一个具体工厂ConcreteFactory_B
同理。客户端使用时,需要声明一个抽象工厂AbstractFactory
和两个抽象产品AbstractProduct
。
1.2 抽象工厂模式的栗子
篮球保管室可以提供篮球和篮球衣,足球保管室可以提供足球和足球衣。Jungle只要根据心情去某个保管室,就可以换上球衣、拿上球,然后就可以愉快地玩耍了。
对应的UML实例图:
二、AbstractFactory.h头文件
//抽象工厂类
class AbstractFactory
{
public:
virtual AbstractBall *getBall() = 0;
virtual AbstractShirt *getShirt() = 0;
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
注意上面的抽象工厂类中定义两个纯虚函数。
//抽象产品类AbstractBall
class AbstractBall
{
public:
AbstractBall(){}
//抽象方法:
void play(){};
};
//具体产品类Basketball
class Basketball :public AbstractBall
{
public:
Basketball(){
play();
}
//具体实现方法
void play(){
printf("Jungle play Basketball\n\n");
}
};
//具体产品类Football
class Football :public AbstractBall
{
public:
Football(){
play();
}
//具体实现方法
void play(){
printf("Jungle play Football\n\n");
}
};
//抽象产品类AbstractShirt
class AbstractShirt
{
public:
AbstractShirt(){}
//抽象方法:
void wearShirt(){};
};
//具体产品类BasketballShirt
class BasketballShirt :public AbstractShirt
{
public:
BasketballShirt(){
wearShirt();
}
//具体实现方法
void wearShirt(){
printf("Jungle wear Basketball Shirt\n\n");
}
};
//具体产品类FootballShirt
class FootballShirt :public AbstractShirt
{
public:
FootballShirt(){
wearShirt();
}
//具体实现方法
void wearShirt(){
printf("Jungle wear Football Shirt\n\n");
}
};
//抽象工厂类
class AbstractFactory
{
public:
virtual AbstractBall *getBall() = 0;
virtual AbstractShirt *getShirt() = 0;
};
//具体工厂类BasketballFactory
class BasketballFactory :public AbstractFactory
{
public:
BasketballFactory(){
printf("BasketballFactory\n");
}
AbstractBall *getBall(){
printf("Jungle get basketball\n");
return new Basketball();
}
AbstractShirt *getShirt(){
printf("Jungle get basketball shirt\n");
return new BasketballShirt();
}
};
//具体工厂类BasketballFactory
class FootballFactory :public AbstractFactory
{
public:
FootballFactory(){
printf("FootballFactory\n");
}
AbstractBall *getBall(){
printf("Jungle get football\n");
return new Football();
}
AbstractShirt *getShirt(){
printf("Jungle get football shirt\n");
return new FootballShirt();
}
};
- 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
三、客户端代码
#include <iostream>
#include "AbstractFactory.h"
int main()
{
printf("抽象工厂模式\n");
//定义工厂类对象和产品类对象
AbstractFactory *fac = NULL;
AbstractBall *ball = NULL;
AbstractShirt *shirt = NULL;
fac = new BasketballFactory();
ball = fac->getBall();
shirt = fac->getShirt();
fac = new FootballFactory();
ball = fac->getBall();
shirt = fac->getShirt();
system("pause");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
文章来源: andyguo.blog.csdn.net,作者:山顶夕景,版权归原作者所有,如需转载,请联系作者。
原文链接:andyguo.blog.csdn.net/article/details/123011153
- 点赞
- 收藏
- 关注作者
评论(0)