设计模式(三)——抽象工厂模式
设计模式(三)--抽象工厂模式
一、抽象工厂模式
1、抽象工厂模式简介
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
UML类图:
2、抽象工厂模式角色
(1)抽象工厂AbstractFactory:抽象工厂类,提供创建两种产品的接口CreateProductA和CreateProductB,由派生的各个具体工厂类对其实现
(2)具体工厂:包括具体工厂FactoryM和具体工厂FactoryN。具体工厂FactoryM用于生产具体产品MProductA和具体产品MProductB,具体工厂FactoryN用于生产具体产品NProductA和具体产品NProductB。
(3)抽象产品:AbstractProductA、AbstractProductB:分别代表两种不同类型的产品,由具体的产品派生类对其实现
(4)具体产品:包括抽象产品AbstractProductA所对应的具体产品MProductA和NProductA,抽象产品AbstractProductB所对应的具体产品MProductB和NProductB。
3、抽象工厂模式优缺点
优点:抽象工厂模式是对工厂方法模式的改进,用于处理产品不只有一类的情况。抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。
抽象工厂模式分离了具体类,使得客户与类的实现分离
缺点:
难以支持新种类的产品,不容易扩展。产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
抽象工厂模式和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。
4、抽象工厂模式使用场景
抽象工厂模式使用场景:
A、当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。
B、 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节。
C、同属于同一个产品族的产品是在一起使用的,约束必须在系统的设计中体现出来。
D、系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。
二、抽象工厂模式实现
抽象工厂AbstractFactory类:#ifndef ABSTRACTFACTORY_H#define ABSTRACTFACTORY_H class AbstractProductA;class AbstractProductB;class AbstractFactory{public: virtual AbstractProductA* createProductA() = 0; virtual AbstractProductB* createProductB() = 0;}; #endif // ABSTRACTFACTORY_HFactoryM工厂类:#ifndef FACTORYM_H#define FACTORYM_H#include "AbstractFactory.h"#include "MProductA.h"#include "MProductB.h" class FactoryM : public AbstractFactory{public: virtual AbstractProductA* createProductA() { AbstractProductA* product = new MProductA(); return product; } virtual AbstractProductB* createProductB() { AbstractProductB* product = new MProductB(); return product; }}; #endif // FACTORYM_HFactoryN工厂类:#ifndef FACTORYN_H#define FACTORYN_H#include "AbstractFactory.h"#include "NProductA.h"#include "NProductB.h" class FactoryN : public AbstractFactory{public: virtual AbstractProductA* createProductA() { AbstractProductA* product = new NProductA(); return product; } virtual AbstractProductB* createProductB() { AbstractProductB* product = new NProductB(); return product; }}; #endif // FACTORYN_H AbstractProductA抽象产品A类:#ifndef ABSTRACTPRODUCTA_H#define ABSTRACTPRODUCTA_H class AbstractProductA{public: virtual void productMethod() = 0;}; #endif // ABSTRACTPRODUCTA_HMProductA产品类:#ifndef MPRODUCTA_H#define MPRODUCTA_H#include "AbstractProductA.h"#includeusing std::endl;using std::cout; class MProductA : public AbstractProductA{public: virtual void productMethod() { cout << "This is a MProductA by FactoryM" << endl; }}; #endif // MPRODUCTA_H NProductA产品类:#ifndef NPRODUCTA_H#define NPRODUCTA_H#include "AbstractProductA.h"#include using std::endl;using std::cout; class NProductA : public AbstractProductA{public: virtual void productMethod() { cout << "This is a NProductA by FactoryN" << endl; }}; #endif // NPRODUCTA_H AbstractProductB抽象产品B类:#ifndef ABSTRACTPRODUCTB_H#define ABSTRACTPRODUCTB_H class AbstractProductB{public: virtual void productMethod() = 0;}; #endif // ABSTRACTPRODUCTB_HMProductB产品类:#ifndef MPRODUCTB_H#define MPRODUCTB_H#include "AbstractProductB.h"#include using std::endl;using std::cout; class MProductB : public AbstractProductB{public: virtual void productMethod() { cout << "This is a MProductB by FactoryM" << endl; }}; #endif // MPRODUCTB_HNProductB产品类:#ifndef NPRODUCTB_H#define NPRODUCTB_H#include "AbstractProductB.h"#include using std::endl;using std::cout; class NProductB : public AbstractProductB{public: virtual void productMethod() { cout << "This is a NProductB by FactoryN" << endl; }}; #endif // NPRODUCTB_H客户调用程序:#include #include "AbstractFactory.h"#include "FactoryM.h"#include "FactoryN.h" using namespace std; int main(){ AbstractFactory* factoryM = new FactoryM(); AbstractProductA* mproductA = factoryM->createProductA(); AbstractProductB* mproductB = factoryM->createProductB(); mproductA->productMethod(); mproductB->productMethod(); AbstractFactory* factoryN = new FactoryN(); AbstractProductA* nproductA = factoryN->createProductA(); AbstractProductB* nproductB = factoryN->createProductB(); nproductA->productMethod(); nproductB->productMethod(); delete factoryM; delete mproductA; delete mproductB; delete factoryN; delete nproductA; delete nproductB; return 0;}