在簡單工廠模式中,咱們講過簡單工廠模式的一個缺點就是在擴展時會違背開閉原則。工廠模式就是針對簡單工廠模式擴展性上的一種改進。工廠模式(Factory Method),定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使的實例化延遲到了其子類(其實就是在簡單工廠模式的UML圖中在生產端造成了相似產品端的繼承體系)。客戶在使用時須要知道它的產品是由哪個工廠生產的。ios
工廠模式的實現,客戶端須要決定示例化哪個工廠來實例化對象,選擇判斷的問題仍是存在的,也就是說,工廠方法把原來簡單工廠模式的內部邏輯判斷移到了客戶端代碼進行,你想要加功能,原本是修改工廠類,而如今是修改客戶端。設計模式
從總體結構上來講,工廠模式有4個大組件:1.工廠虛基類:抽象工廠,提供方法指導子類的行爲;2.工廠虛基類的子類:實現其父類的接口,主要用於建立具體產品。3.產品虛基類:抽象產品,你能夠視爲這是一個產品的模具。它只能生產符合模具要求的產品;4.產品虛基類的子類:根據本身的狀況實現其父類提供的接口。ide
這裏要注意一下,咱們能夠在使用子類指針的狀況下使用其父類指針進行替代,可是前提是,父類和子類必需要具備相同的類聲明。(運行時多態)學習
1.抽象工廠類:spa
#ifndef ABSTRACTFACTORY_H_ #define ABSTRACTFACTORY_H_ #include "AbstractProduct.h" class AbstractFactory { public: AbstractFactory() = default; virtual ~AbstractFactory() = default; virtual AbstractProduct* createProduct() = 0; }; #endif
2.抽象產品類:設計
#ifndef ABSTRACTPRODUCT_H_ #define ABSTRACTPRODUCT_H_ class AbstractProduct { public: int m_iLeftOper{0}; int m_iRightOper{0}; virtual const int getLeftOper() const =0; virtual const int getRightOper() const = 0; virtual void setLeftOper(const int iLeftOper) = 0; virtual void setRightOper(const int iRightOper) = 0; virtual int operate() const = 0; AbstractProduct() = default; virtual ~AbstractProduct() = default; }; #endif
3.具體的產品類:指針
#ifndef ADDOPERATION_H_ #define ADDOPERATION_H_ #include "AbstractProduct.h" class AddOperation:public AbstractProduct { public: const int getLeftOper() const override { return m_iLeftOper; } const int getRightOper() const override { return m_iRightOper; } void setLeftOper(const int iLeftOper) override { m_iLeftOper = iLeftOper; } void setRightOper(const int iRightOper) override { m_iRightOper = iRightOper; } int operate() const override { return m_iRightOper + m_iLeftOper; } }; #endif
顯然,在咱們第一個版本的時候只有一個產品須要使用,這個產品就是AddOperation,要想使用這個產品咱們必需要實現一個具體的工廠類,專門用於生產這一類型的實例:code
4.具體的工廠類:對象
AddOperationFactory.hblog
#include "AddOperationFactory.h" AbstractProduct* AddOperationFactory::createProduct() { return new AddOperation(); }
5.客戶端對這個工廠類的使用:
#include "AddOperationFactory.h" #include "AbstractFactory.h" #include <iostream> using namespace std; int main(int argc,char *argv[]) { AbstractFactory *objAbstractFactory = new AddOperationFactory(); auto objAdd = objAbstractFactory->createProduct(); objAdd->setLeftOper(1); objAdd->setRightOper(2); cout << objAdd->operate() << endl; cout << "LeftOper is "<< objAdd->getLeftOper() << endl; cout << "RightOper is " << objAdd->getRightOper() << endl; if(nullptr != objAbstractFactory) { delete objAbstractFactory; objAbstractFactory = nullptr; } if(nullptr != objAdd) { delete objAdd; objAdd = nullptr; } return(1); }
我這個示例就是一個簡單的四則運算,第一次只支持加法運算,假設第二個版本的時候,老闆讓加一個減法運算,那麼這個時候我須要作三件事情,一個是由AbstractProduct類派生出一個減法類,第二個事情是由AbstractFactory類派生出一個用於產生減法類實例的減法工廠。第三個事情,假設減法類,叫作SubOperation,減法工廠叫作SubOperationFactory。在客戶端使用這個工廠的時候,咱們要使用SubOperationFactory類來生產SubOperation的實例。就是說客戶端將會出現以下代碼:
#include "AddOperationFactory.h" #include "AbstractFactory.h" #include "SubOperationFactory.h" #include "SubOperation.h" #include <iostream> using namespace std; int main(int argc,char *argv[]) { AbstractFactory *objAbstractFactory = new AddOperationFactory(); auto objAdd = objAbstractFactory->createProduct(); objAdd->setLeftOper(1); objAdd->setRightOper(2); cout << objAdd->operate() << endl; cout << "LeftOper is "<< objAdd->getLeftOper() << endl; cout << "RightOper is " << objAdd->getRightOper() << endl; if(nullptr != objAbstractFactory) { delete objAbstractFactory; objAbstractFactory = nullptr; } if(nullptr != objAdd) { delete objAdd; objAdd = nullptr; } AbstractFactory *objSubFactory = new SubOperationFactory(); AbstractProduct *objSubOperation = objSubFactory->createProduct(); objSubOperation->setLeftOper(3); objSubOperation->setRightOper(1); std::cout << objSubOperation->operate() << end; if(nullptr != objSubFactory) { delete objSubFactory; objSubFactory = nullptr; } if(nullptr != objSubOperation) { delete objSubOperation; objSubOperation = nullptr; } return(1); }
工廠模式和簡單工廠模式都是集中分裝了對象的建立,使得更換對象時,不須要作太大的改動便可實現,下降了客戶程序與產品的耦合度。工廠模式是簡單工廠模式的進一步抽象和推廣,它克服了簡單工廠模式帶來的違法開放-封閉原則的缺點,可是本身的缺點是,沒增長一個新的產品,就要加一個產品工廠的類,增長了額外的開發量。另外在生產具體的產品時,客戶端必需要知道它須要的產品將由哪一個類(工廠)生產。
第一次學習設計模式,歡迎指正。