從新思考一下前兩篇文章提到的芯片設計軟件,factory method模式能夠經過實例化 RoundFactory,RecFactory和TriFactory來分別實現 MaskRound, MaskRec和MaskTri對象,將在掩模上設計圓形,矩形和三角形的功能延遲到子類當中,不過 MaskRound,MaskRec和MaskTri都繼承自同一種Mask,假設如今光刻技術有了新的突破,須要在新的類型的Mask上設計芯片圖形,factory method就無能爲力了,這就要用到本文講的abstract factory模式。ios
假設如今有兩種掩模,maskA和maskB,abstract factory模式的類結構圖以下:安全
maskA和maskB是兩個獨立的產品系列,具備獨立的 MaskRound,MaskRec和MaskTri子類。 FigureFactory分別定義 CreateFigureA和 CreateFigureB建立maksA和maskB的圖形。函數
代碼實現以下:spa
//maskA.hpp #ifndef MASKA_HPP #define MASKA_HPP class 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_HPP class 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適用於:prototype
1. 系統獨立於產品建立,組合和表示時設計
2. 系統具備多個產品系列code
3. 強調一系列相關產品的設計對象
4. 使用產品類庫,只想顯示接口blog
同時具備一些優缺點:繼承
1. 方便更換產品系列,只要更換factory對象便可。
2. 有利於產品的一致性,每種factory只支持建立一個系列對象。
3. 難以支持新新產品。繼承的接口肯定了能夠被建立的對象集合,有新添加的類型時,必須擴展接口,涉及到全部子類的改變,一個更加靈活但不太安全的方法是參數化建立對象的函數。
Abstract factory大部分狀況下是用factory method模式實現的,可是也能夠用上篇文章中的prototype模式實現。因爲每一個factory都負責同一系列對象建立,一般實現爲singleton。