前言
前面有两篇文章分别介绍了简单工厂模式和工厂方法模式,这两种模式都比较常见,今天介绍工厂模式的最后一种,抽象工厂模式。
抽象工厂模式(Abstract Factory Pattern)是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
UML 类图
来看一下抽象工厂模式的类图结构。
IFactory : 抽象工厂基类ConcreteFactory1:具体产品的工厂类,继承于IFactory,并实现基类中的产品接口ProductA :产品基类ConcreteProductA : 具体的产品类,由具体的产品工厂创建
适用场景
可以在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
示例
我们还是根据前两节的示例来进行扩展:
factory.h
#include "product.h"class IFactory{public:enum FactoryType{RECTANGLE,CIRCLE,TRIANGE};IFactory();virtual ~IFactory();virtual IShape * createShape() = 0;virtual IColor * createColor() = 0;static IFactory * createFactor(FactoryType type);};class RectangleFactory : public IFactory{public:RectangleFactory() {}~RectangleFactory();IShape * createShape();IColor * createColor();};class CircleFactory : public IFactory{public:CircleFactory() {}~CircleFactory();IShape * createShape();IColor * createColor();};class TriangeFactory : public IFactory{public:TriangeFactory() {}~TriangeFactory();IShape * createShape();IColor * createColor();};
factory.cpp
#include "factory.h"IFactory::IFactory(){}IFactory::~IFactory(){}IFactory *IFactory::createFactor(IFactory::FactoryType type){IFactory * factory = nullptr;switch (type) {case RECTANGLE:factory = new RectangleFactory();break;case CIRCLE:factory = new CircleFactory();break;case TRIANGE:factory = new TriangeFactory();break;default:break;}return factory;}RectangleFactory::~RectangleFactory(){}IShape *RectangleFactory::createShape(){return new Rectangle();}IColor *RectangleFactory::createColor(){return new RectangleColor();}CircleFactory::~CircleFactory(){}IShape *CircleFactory::createShape(){return new Circle();}IColor *CircleFactory::createColor(){return new CircleColor();}TriangeFactory::~TriangeFactory(){}IShape *TriangeFactory::createShape(){return new Triange();}IColor *TriangeFactory::createColor(){return new TriangeColor();}
product.h
#include <iostream>using namespace std;class IShape{public:IShape();virtual ~IShape();virtual void draw() = 0;};class IColor{public:IColor();virtual ~IColor();virtual void brush() = 0;};class Rectangle : public IShape{public:Rectangle(){}~Rectangle(){}void draw();};class Circle : public IShape{public:Circle(){}~Circle(){}void draw();};class Triange : public IShape{public:Triange(){}~Triange(){}void draw();};class RectangleColor : public IColor{public:RectangleColor(){}~RectangleColor(){}void brush();};class CircleColor : public IColor{public:CircleColor(){}~CircleColor(){}void brush();};class TriangeColor : public IColor{public:TriangeColor(){}~TriangeColor(){}void brush();};
product.cpp
#include "product.h"IShape::IShape(){}IShape::~IShape(){}void Triange::draw(){cout << "draw Triange.." << endl;}void Circle::draw(){cout << "draw Circle.." << endl;}void Rectangle::draw(){cout << "draw Rectangle.." << endl;}IColor::IColor(){}IColor::~IColor(){}void RectangleColor::brush(){cout << "Rectangle brush Red.."<< endl;}void CircleColor::brush(){cout << "Circle brush Blue.."<< endl;}void TriangeColor::brush(){cout << "Triange brush green.."<< endl;}
main.cpp
#include <iostream>#include "factory.h"using namespace std;#define DELETE(x) {if(x){delete(x);(x) = nullptr;}}int main(){//RectangleIFactory * pFactory = IFactory::createFactor(IFactory::RECTANGLE);IShape * pShape = pFactory->createShape();IColor * pColor = pFactory->createColor();pShape->draw();pColor->brush();DELETE(pFactory);DELETE(pShape);DELETE(pColor);//CirclepFactory = IFactory::createFactor(IFactory::CIRCLE);pShape = pFactory->createShape();pColor = pFactory->createColor();pShape->draw();pColor->brush();DELETE(pFactory);DELETE(pShape);DELETE(pColor);//TriangepFactory = IFactory::createFactor(IFactory::TRIANGE);pShape = pFactory->createShape();pColor = pFactory->createColor();pShape->draw();pColor->brush();DELETE(pFactory);DELETE(pShape);DELETE(pColor);return 0;}
从以上代码可以看到,我们要通过一个静态函数来创建不同的工厂类型,这用法有点类似简单工厂模式的用法,原理差不多的,那么在用的时候只需要传入不同类型就可以创建对应的工厂了,而在每一个具体的工厂中又会对应创建不同的产品出来。
抽象工厂模式的优劣
优点:这种结构封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂即可。并且可以支持不同类型的产品,使得模式灵活性更强。然后可以非常容易的就创建工厂中一系列的产品出来。
缺点:代码结构比较臃肿,初次接触可能不太容易理解。并且每新增一个产品,所有工厂类都需要添加一个接口,违背了开放-封闭原则,所以该方法通常在产品不会经常变动的情况下使用。
参考资料:《设计模式》