设计模式(4)抽象工厂模式

抽象工厂模式

之前看到的两个设计模式,都存在各自的缺陷,简单工厂模式中,一个工厂生产多个产品,根据客户提供的产品名称创建对应的产品实例;工厂方法设计模式,则在简单工厂模式的工厂上,创建了许多个工厂类,根据客户提供的产品名称选择可以生产对应产品的工厂进行生产。

然而,很多时候,一个工厂生产的产品并不单一,而是生产一类产品,比如,一个工厂,可以生产足球、篮球、排球等多种产品,把相关的产品归纳为一个“产品族”,由同一个工厂来生产,这就是抽象工厂模式。

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。其抽象程度更高,每一个具体工厂可以生产一组相关的具体产品对象。

抽象工厂模式结构

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

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

其UML类图如下:
在这里插入图片描述
可以看出,具体工厂A可以生产两种产品,工厂B也可以生产两种产品。在使用客户端时,只需要声明一个抽象工厂AbstractFactory和两个抽象产品AbstractProduct。
直接上个例子:

abstractfactory.h

#include <iostream>
#include <string.h>

using namespace std;

//抽象产品类AbstractBall
class AbstractBall
{
    
    
public:
	AbstractBall(){
    
    

	}
	//抽象方法:
	void play(){
    
    };
};

//具体产品类Basketball
class Basketball :public AbstractBall
{
    
    
public:
	Basketball(){
    
    
		play();
	}
	//具体实现方法
	void play(){
    
    
		cout << "Play Basketball\n\n";
	}
};

//具体产品类Football
class Football :public AbstractBall
{
    
    
public:
	Football(){
    
    
		play();
	}
	//具体实现方法
	void play(){
    
    
		cout << "Play Football\n\n";
	}
};

//抽象产品类AbstractShirt
class AbstractShirt
{
    
    
public:
	AbstractShirt(){
    
    }
	//抽象方法:
	void wearShirt(){
    
    };
};

//具体产品类BasketballShirt
class BasketballShirt :public AbstractShirt
{
    
    
public:
	BasketballShirt(){
    
    
		wearShirt();
	}
	//具体实现方法
	void wearShirt(){
    
    
		cout << "Wear Basketball Shirt\n\n";
	}
};

//具体产品类FootballShirt
class FootballShirt :public AbstractShirt
{
    
    
public:
	FootballShirt(){
    
    
		wearShirt();
	}
	//具体实现方法
	void wearShirt(){
    
    
		cout << "wear Football Shirt\n\n";
	}
};

//抽象工厂类
class AbstractFactory
{
    
    
public:
	virtual AbstractBall *getBall() = 0;
	virtual AbstractShirt *getShirt() = 0;
};

//具体工厂类BasketballFactory
class BasketballFactory :public AbstractFactory
{
    
    
public:
	BasketballFactory(){
    
    
		cout << "BasketballFactory\n";
	}
	AbstractBall *getBall(){
    
    
		cout << "Get basketball\n";
		return new Basketball();
	}
	AbstractShirt *getShirt(){
    
    
		cout << "Get basketball shirt\n";
		return new BasketballShirt();
	}
};

//具体工厂类BasketballFactory
class FootballFactory :public AbstractFactory
{
    
    
public:
	FootballFactory(){
    
    
		cout << "FootballFactory\n";
	}
	AbstractBall *getBall(){
    
    
		cout << "Get football\n";
		return new Football();
	}
	AbstractShirt *getShirt(){
    
    
		cout << "Get football shirt\n";
		return new FootballShirt();
	}
};

abstractfactory.cpp

#include <iostream>
#include "abstractfactory.h"

int main()
{
    
    
	AbstractFactory *fac = NULL;
	AbstractBall *ball = NULL;
	AbstractShirt *shirt = NULL;

	fac = new BasketballFactory();
	ball = fac->getBall();
	shirt = fac->getShirt();
	delete fac;
	delete ball;
	delete shirt;

	fac = new FootballFactory();
	ball = fac->getBall();
	shirt = fac->getShirt();
	delete fac;
	delete ball;
	delete shirt;

	return 0;
}

抽象工厂模式总结

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

优点:

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

缺点:

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

适用环境:

  • 一系列/一族产品需要被同时使用时,适合使用抽象工厂模式;
  • 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品

猜你喜欢

转载自blog.csdn.net/qq_24649627/article/details/115069815