天天看点

【C++设计模式】抽象工厂模式

学习总结

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

  • 抽象工厂模式的优点:
  • 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
  • 新加入产品系列时,无需修改原有系统,增强了系统的可扩展性,符合开闭原则。
  • 抽象工厂模式的缺点:
  • 在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则
  • 适用环境:
  • 一系列/一族产品需要被同时使用时,适合使用抽象工厂模式;
  • 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品
抽象工厂模式中,如果需要新增加一个系列的产品,比如足球系列,只需增加一族新的具体产品类(抽象和具体)并提供一个对应的工厂类即可。但是,如果要在已有的产品族里增加另一个产品,比如Jungle打篮球,除了需要篮球和篮球衣外,Jungle还想换双篮球鞋,这时候该怎么办呢?是不是要去修改BasketballFactory呢?

文章目录

  • ​​学习总结​​
  • ​​一、抽象工厂模式​​
  • ​​1.1 抽象工厂模式结构​​
  • ​​1.2 抽象工厂模式的栗子​​
  • ​​二、AbstractFactory.h头文件​​
  • ​​三、客户端代码​​

一、抽象工厂模式

抽象工厂模式,其抽象程度更高,每一个具体工厂可以生产一组相关的具体产品对象。

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

1.1 抽象工厂模式结构

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

  • 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
  • 具体工厂(ConcreteFactory):生产具体的产品
  • 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
  • 具体产品(ConcreteProduct):具体的产品类
【C++设计模式】抽象工厂模式

结合抽象工厂模式定义和UML,可以看到具体工厂​

​ConcreteFactory_A​

​​可以生产两种产品,分别是​

​ConcreteProduct_A_1​

​​和​

​ConcreteProduct_A_2​

​​,另一个具体工厂​

​ConcreteFactory_B​

​​同理。客户端使用时,需要声明一个抽象工厂​

​AbstractFactory​

​​和两个抽象产品​

​AbstractProduct​

​。

1.2 抽象工厂模式的栗子

篮球保管室可以提供篮球和篮球衣,足球保管室可以提供足球和足球衣。Jungle只要根据心情去某个保管室,就可以换上球衣、拿上球,然后就可以愉快地玩耍了。

【C++设计模式】抽象工厂模式

对应的UML实例图:

【C++设计模式】抽象工厂模式

二、AbstractFactory.h头文件

//抽象工厂类
class AbstractFactory
{
public:
  virtual AbstractBall *getBall() = 0;
  virtual AbstractShirt *getShirt() = 0;
};      
//抽象产品类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();
  }
};      

三、客户端代码

#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;
}      

继续阅读