首页 > 代码库 > 设计模式系列之抽象工厂模式

设计模式系列之抽象工厂模式

重新思考一下前两篇文章提到的芯片设计软件,factory method模式可以通过实例化 RoundFactory,RecFactory和TriFactory来分别实现 MaskRound, MaskRec和MaskTri对象,将在掩模上设计圆形,矩形和三角形的功能延迟到子类当中,不过 MaskRound,MaskRec和MaskTri都继承自同一种Mask,假设现在光刻技术有了新的突破,需要在新的类型的Mask上设计芯片图形,factory method就无能为力了,这就要用到本文讲的abstract factory模式。

假设现在有两种掩模,maskA和maskB,abstract factory模式的类结构图如下:

maskA和maskB是两个独立的产品系列,具有独立的 MaskRound,MaskRec和MaskTri子类。 FigureFactory分别定义 CreateFigureA和 CreateFigureB创建maksA和maskB的图形。

代码实现如下:

//maskA.hpp#ifndef MASKA_HPP#define MASKA_HPPclass MaskAFigure{  public:    virtual ~MaskAFigure()=0;  protected:    MaskAFigure();};class MaskARound:public MaskAFigure {  public:    MaskARound();    ~MaskARound();};class MaskARec:public MaskAFigure {  public:    MaskARec();    ~MaskARec();};class MaskATri:public MaskAFigure {  public:    MaskATri();    ~MaskATri();};#endif//maskA.cpp#include <iostream>#include "maskA.hpp"using std::cout;using std::endl;MaskAFigure::MaskAFigure() {}MaskAFigure::~MaskAFigure() {}MaskARound::MaskARound() {  cout<<"Draw roundness on MaskA"<<endl;}MaskARound::~MaskARound() {}MaskARec::MaskARec() {  cout<<"Draw rectangle on MaskA"<<endl;}MaskARec::~MaskARec() {}MaskATri::MaskATri() {  cout<<"Draw triangle on MaskA"<<endl;}MaskATri::~MaskATri() {}//maskB.hpp#ifndef MASKB_HPP#define MASKB_HPPclass MaskBFigure{  public:    virtual ~MaskBFigure()=0;  protected:    MaskBFigure();};class MaskBRound:public MaskBFigure {  public:    MaskBRound();    ~MaskBRound();};class MaskBRec:public MaskBFigure {  public:    MaskBRec();    ~MaskBRec();};class MaskBTri:public MaskBFigure {  public:    MaskBTri();    ~MaskBTri();};#endif//maskB.cpp#include <iostream>#include "maskB.hpp"using std::cout;using std::endl;MaskBFigure::MaskBFigure() {}MaskBFigure::~MaskBFigure() {}MaskBRound::MaskBRound() {  cout<<"Draw roundness on MaskB"<<endl;}MaskBRound::~MaskBRound() {}MaskBRec::MaskBRec() {  cout<<"Draw rectangle on MaskB"<<endl;}MaskBRec::~MaskBRec() {}MaskBTri::MaskBTri() {  cout<<"Draw triangle on MaskB"<<endl;}MaskBTri::~MaskBTri() {}//abstractfactory.hpp#ifndef ABSTRACT_MASKFACTORY_HPP#define ABSTRACT_MASKFACTORY_HPP#include "maskB.hpp"#include "maskA.hpp"class FigureFactory { public:  virtual ~FigureFactory()=0;  virtual MaskAFigure* CreateFigureA()=0;  virtual MaskBFigure* CreateFigureB()=0; protected:  FigureFactory();};class RoundFactory:public FigureFactory { public:  RoundFactory();  ~RoundFactory();  MaskARound* CreateFigureA();  MaskBRound* CreateFigureB();};class RecFactory:public FigureFactory { public:  RecFactory();  ~RecFactory();  MaskARec* CreateFigureA();  MaskBRec* CreateFigureB();};class TriFactory:public FigureFactory { public:  TriFactory();  ~TriFactory();  MaskATri* CreateFigureA();  MaskBTri* CreateFigureB();};#endif//abstractfactory.cpp#include <iostream>#include "abstractfactory.hpp"using std::cout;using std::endl;FigureFactory::FigureFactory() {}FigureFactory::~FigureFactory() {}RoundFactory::RoundFactory() {  cout<<"Init RoundFactory"<<endl;}RoundFactory::~RoundFactory() {}MaskARound* RoundFactory::CreateFigureA() {  return new MaskARound();}MaskBRound* RoundFactory::CreateFigureB() {  return new MaskBRound();}RecFactory::RecFactory() {  cout<<"Init RecFactory"<<endl;}RecFactory::~RecFactory() {}MaskARec* RecFactory::CreateFigureA() {  return new MaskARec();}TriFactory::TriFactory() {  cout<<"Init TriFactory"<<endl;}TriFactory::~TriFactory() {}MaskATri* TriFactory::CreateFigureA() {  return new MaskATri();}MaskBTri* TriFactory::CreateFigureB() {  return new MaskBTri();}//main.cpp#include <iostream>#include <memory>#include "abstractfactory.hpp"using std::cout;using std::endl;using std::shared_ptr;int main() {  shared_ptr<RoundFactory> rof(new RoundFactory());  shared_ptr<MaskARound>    maro(rof->CreateFigureA());  shared_ptr<MaskBRound>    mbro(rof->CreateFigureB());  shared_ptr<RecFactory>   ref(new RecFactory());  shared_ptr<MaskARec>    mare(ref->CreateFigureA());  shared_ptr<MaskBRec>    mbre(ref->CreateFigureB());  shared_ptr<TriFactory>  tif(new TriFactory());  shared_ptr<MaskATri>    matr(tif->CreateFigureA());  shared_ptr<MaskBTri>    mbtr(tif->CreateFigureB());}

abstract factory适用于:

1. 系统独立于产品创建,组合和表示时

2. 系统具有多个产品系列

3. 强调一系列相关产品的设计

4. 使用产品类库,只想显示接口

同时具有一些优缺点:

1. 方便更换产品系列,只要更换factory对象即可。

2. 有利于产品的一致性,每种factory只支持创建一个系列对象。

3. 难以支持新新产品。继承的接口确定了可以被创建的对象集合,有新添加的类型时,必须扩展接口,涉及到所有子类的改变,一个更加灵活但不太安全的方法是参数化创建对象的函数。

Abstract factory大部分情况下是用factory method模式实现的,但是也可以用上篇文章中的prototype模式实现。由于每个factory都负责同一系列对象创建,通常实现为singleton。

设计模式系列之抽象工厂模式