(四)工廠方法

  • 工廠類集中了所有實例(產品)的創建邏輯,一旦這個工廠不能正常工作,整個系統都會受到影響;
  • 違背“開放 - 關閉原則”,一旦添加新產品就不得不修改工廠類的邏輯,那樣就需要工廠類中做判斷(比如:if),根據不同的條件或者前提創建不同的對象。這也就造成了,當增加新的產品時,需要修改工廠類,也就是其增加其判斷分支。
  • 簡單工廠模式由於使用了靜態工廠方法,靜態方法不能被繼承和重寫,會造成工廠角色無法形成基於繼承的等級結構。

  • 工廠方法模式,又稱工廠模式、多態工廠模式和虛擬構造器模式,通過定義一個抽象工廠類來負責定義公共的接口,而其子類負責到底實例化哪個類,那麼該類的實例化將(具體產品的創建)延遲到工廠類的子類(具體工廠)中完成,即由子類來決定應該實例化(創建)哪一個類。
  • 工廠方法模式之所以可以解決簡單工廠的問題,是因爲工廠方法模式把具體產品的創建推遲到工廠類的子類(具體工廠)中,此時工廠類不再負責所有產品的創建,而只是給出具體工廠必須實現的接口,而不接觸哪一個產品類應當被實例化這種細節。這樣工廠方法模式在添加新產品的時候就不修改工廠類邏輯而是添加新的工廠子類,符合開放封閉原則,克服了簡單工廠模式中缺點。

使用步驟

  • 步驟1: 創建抽象工廠類,定義具體工廠的公共接口;
  • 步驟2: 創建抽象產品類 ,定義具體產品的公共接口;
  • 步驟3: 創建具體產品類(繼承抽象產品類)和 定義生產的具體產品;
  • 步驟4:創建具體工廠類(繼承抽象工廠類),定義創建對應具體產品實例的方法;
  • 步驟5:外界通過調用具體工廠類的方法,從而創建不同 ConcreteProduct 類的實例

通過計算器(加減乘除)來講解工廠方式

代碼實現:

#include<iostream>
#include<string>
#include<vector>
#include<stack>

using namespace std;

/**
 * 計算器運算抽象類
 */
class Operation {
private:
    double numberA;//操作數A
    double numberB;//操作數B
public:
    /**
     * 抽象方法
     * 獲得操作結果
     */
    virtual double getResult() = 0;

    /**
     * 獲取 操作數A
     */
    double getNumberA() {
        return this->numberA;
    }

    /**
     * 設置 操作數A
     */
    void setNumberA(double numberA) {
        this->numberA = numberA;
    }

    /**
     * 獲取 操作數B
     */
    double getNumberB() {
        return this->numberB;
    }

    /**
     * 設置 操作數B
     */
    void setNumberB(double numberB) {
        this->numberB = numberB;
    }
};

/**
 * 加法運算類
 */
class OperationAdd: public Operation {
public:
    double getResult() {
        return getNumberA() + getNumberB();
    }
};

/**
 * 減法運算類
 */
class OperationSub: public Operation {
    double getResult() {
        return getNumberA() - getNumberB();
    }
};

/**
 * 乘法運算類
 */
class OperationMul: public Operation {
    double getResult() {
        return getNumberA() * getNumberB();
    }
};

/**
 * 除法運算類
 */
class OperationDiv: public Operation {
    double getResult() {
        double num = getNumberB();
        if(num == 0)
            throw "Division by zero condition!";
        return getNumberA() / getNumberB();
    }
};

/**
 * 工廠接口
 */
class IFactory {
public:
    virtual Operation* createOperation() = 0;
};

/**
 * 加法工廠實現類
 */
class AddFactory: public IFactory{
    Operation* createOperation()
    {
        return new OperationAdd();
    }
};

/**
 * 減法工廠實現類
 */
class SubFactory: public IFactory{
    Operation* createOperation()
    {
        return new OperationSub();
    }
};

/**
 * 乘法工廠實現類
 */
class MulFactory: public IFactory{
    Operation* createOperation()
    {
        return new OperationMul();
    }
};

/**
 * 除法工廠實現類
 */
class DivFactory: public IFactory{
    Operation* createOperation()
    {
        return new OperationDiv();
    }
};

/**
 * 大話設計模式(C++實現)
 * 工廠模式
 */


int main()
{
        IFactory* operFactory = new AddFactory();
        Operation *operation;
        double result;
        operation = operFactory->createOperation();
        operation->setNumberA(1.1);
        operation->setNumberB(2.2);
        result = operation->getResult();
        cout<<"加法結果:"<<result<<endl;

        operFactory = new SubFactory();
        operation = operFactory->createOperation();
        operation->setNumberA(3.3);
        operation->setNumberB(2.2);
        result = operation->getResult();
        cout<<"減法結果:"<<result<<endl;

        operFactory = new MulFactory();
        operation = operFactory->createOperation();
        operation->setNumberA(3.3);
        operation->setNumberB(2.2);
        result = operation->getResult();
        cout<<"乘法結果:"<<result<<endl;

        operFactory = new DivFactory();
        operation = operFactory->createOperation();
        operation->setNumberA(3.3);
        operation->setNumberB(2.2);
        result = operation->getResult();
        cout<<"除法結果:"<<result<<endl;

        return 0;
}

簡單工廠模式的最大優點在於工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態實例化相關的類,對於客戶端來說,去除了與具體產品的依賴.

工廠方法模式實現時,客戶端需要決定實例化哪一個工廠來實現運算類,選擇判斷的問題還是存在的,也就是說,工廠方法把簡單工廠的內部邏輯判斷移到了客戶端代碼來進行,你想要加功能,本來是改工廠類的,而現在是修改客戶端.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章