03 抽象工厂模式

原文转载:https://blog.csdn.net/sinat_21107433/article/details/102618384

回顾之前的设计模式,简单工厂模式所有逻辑都封装在工厂类中,工厂根据客户提供的产品名字创建对应产品的对象实例;工厂方法模式将产品的创建过程放到了具体工厂类中,每一个工厂可以创建一个具体产品,由此可能会创建许多工厂类。很多时候,一个工厂不只是生产一种产品,而是生产一类产品,比如一个体育用品工厂,可以生产篮球、足球、排球等多种产品。此时我们可以把这些相关的产品归纳为一个“产品族”,由同一个工厂来生产,这即是Jungle今天要学习的抽象工厂模式。

1.抽象工厂模式简介

抽象工厂模式是常用的创建型设计模式之一。而今天Jungle要学习的抽象工厂模式,其抽象程度更高,每一个具体工厂可以生产一组相关的具体产品对象

抽象工厂模式定义:

抽象工厂模式:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

简言之,一个工厂可以提供创建多种相关产品的接口,而无需像工厂方法一样,为每一个产品都提供一个具体工厂。 

2.抽象工厂模式结构

抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品:

  • 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
  • 具体工厂(ConcreteFactory):生产具体的产品
  • 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
  • 具体产品(ConcreteProduct):具体的产品类

抽象工厂模式UML类图如下:

结合抽象工厂模式定义和UML,可以看到具体工厂ConcreteFactory_A可以生产两种产品,分别是ConcreteProduct_A_1和ConcreteProduct_A_2,另一个具体工厂ConcreteFactory_B同理。客户端使用时,需要声明一个抽象工厂AbstractFactory和两个抽象产品AbstractProduct

3.抽象工厂模式代码实例

考虑这样一个场景,如下图:

Jungle想要进行户外运动,它可以选择打篮球和踢足球。但这次Jungle不想弄脏原本穿的T恤,所以Jungle还需要穿球衣,打篮球就穿篮球衣,踢足球就穿足球衣。篮球保管室可以提供篮球和篮球衣,足球保管室可以提供足球和足球衣。Jungle只要根据心情去某个保管室,就可以换上球衣、拿上球,然后就可以愉快地玩耍了。

 对应的UML实例图如下图:

3.1.定义产品类

3.1.1.产品类Ball

  • 抽象产品类AbstractBall, 球类的基类,定义抽象方法play
 
  1. //抽象产品类AbstractBall

  2. class AbstractBall

  3. {

  4. public:

  5. AbstractBall(){}

  6. //抽象方法:

  7. void play(){};

  8. };

  • 具体产品类, 分别为BasketballFootball,具体实现方法play
 
  1. //具体产品类Basketball

  2. class Basketball :public AbstractBall

  3. {

  4. public:

  5. Basketball(){

  6. play();

  7. }

  8. //具体实现方法

  9. void play(){

  10. printf("Jungle play Basketball\n\n");

  11. }

  12. };

  13.  
  14. //具体产品类Football

  15. class Football :public AbstractBall

  16. {

  17. public:

  18. Football(){

  19. play();

  20. }

  21. //具体实现方法

  22. void play(){

  23. printf("Jungle play Football\n\n");

  24. }

  25. };

 3.1.2.产品类Shirt

  • 抽象产品类AbstractShirt:球衣类的基类,定义抽象方法wearShirt
 
  1. //抽象产品类AbstractShirt

  2. class AbstractShirt

  3. {

  4. public:

  5. AbstractShirt(){}

  6. //抽象方法:

  7. void wearShirt(){};

  8. };

  • 具体产品类BasketballShirtFootballShirt,具体实现方法wearShirt
 
  1. //具体产品类BasketballShirt

  2. class BasketballShirt :public AbstractShirt

  3. {

  4. public:

  5. BasketballShirt(){

  6. wearShirt();

  7. }

  8. //具体实现方法

  9. void wearShirt(){

  10. printf("Jungle wear Basketball Shirt\n\n");

  11. }

  12. };

  13.  
  14. //具体产品类FootballShirt

  15. class FootballShirt :public AbstractShirt

  16. {

  17. public:

  18. FootballShirt(){

  19. wearShirt();

  20. }

  21. //具体实现方法

  22. void wearShirt(){

  23. printf("Jungle wear Football Shirt\n\n");

  24. }

  25. };

3.2.定义工厂类

  • 定义抽象工厂AbstractFactory,声明两个方法getBall和getShirt
 
  1. //抽象工厂类

  2. class AbstractFactory

  3. {

  4. public:

  5. virtual AbstractBall *getBall() = 0;

  6. virtual AbstractShirt *getShirt() = 0;

  7. };

  • 定义具体工厂BasketballFactoryFootballFactory,重新具体实现两个方法getBall和getShirt
 
  1. //具体工厂类BasketballFactory

  2. class BasketballFactory :public AbstractFactory

  3. {

  4. public:

  5. BasketballFactory(){

  6. printf("BasketballFactory\n");

  7. }

  8. AbstractBall *getBall(){

  9. printf("Jungle get basketball\n");

  10. return new Basketball();

  11. }

  12. AbstractShirt *getShirt(){

  13. printf("Jungle get basketball shirt\n");

  14. return new BasketballShirt();

  15. }

  16. };

  17.  
  18. //具体工厂类BasketballFactory

  19. class FootballFactory :public AbstractFactory

  20. {

  21. public:

  22. FootballFactory(){

  23. printf("FootballFactory\n");

  24. }

  25. AbstractBall *getBall(){

  26. printf("Jungle get football\n");

  27. return new Football();

  28. }

  29. AbstractShirt *getShirt(){

  30. printf("Jungle get football shirt\n");

  31. return new FootballShirt();

  32. }

  33. };

3.3.客户端使用方法示例

 
  1. #include <iostream>

  2. #include "AbstractFactory.h"

  3.  
  4. int main()

  5. {

  6. printf("抽象工厂模式\n");

  7.  
  8. //定义工厂类对象和产品类对象

  9. AbstractFactory *fac = NULL;

  10. AbstractBall *ball = NULL;

  11. AbstractShirt *shirt = NULL;

  12.  
  13. fac = new BasketballFactory();

  14. ball = fac->getBall();

  15. shirt = fac->getShirt();

  16.  
  17. fac = new FootballFactory();

  18. ball = fac->getBall();

  19. shirt = fac->getShirt();

  20.  
  21. system("pause");

  22. return 0;

  23. }

 3.4.效果

4.抽象工厂模式总结

抽象工厂模式中,如果需要新增加一个系列的产品,比如足球系列,只需增加一族新的具体产品类(抽象和具体)并提供一个对应的工厂类即可。但是,如果要在已有的产品族里增加另一个产品,比如Jungle打篮球,除了需要篮球和篮球衣外,Jungle还想换双篮球鞋,这时候该怎么办呢?是不是要去修改BasketballFactory呢?由此,Jungle总结了抽象工厂模式的特点:

优点:

  • 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
  • 新加入产品系列时,无需修改原有系统,增强了系统的可扩展性,符合开闭原则。

缺点:

  • 在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则

适用环境:

  • 一系列/一族产品需要被同时使用时,适合使用抽象工厂模式;
  • 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值