(四)工厂方法

  • 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
  • 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,那样就需要工厂类中做判断(比如: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;
}

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖.

工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,你想要加功能,本来是改工厂类的,而现在是修改客户端.

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