9、[C++]工厂模式

回想一下, 我们之前的简单工厂模式, http://www.cnblogs.com/hanxiao-martin/p/4289502.html

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断, 根据客户端的选择条件动态实例化相关的类, 对于客户端来说, 去除了与具体产品的依赖, 在我们的计算器程序中, 只需要把‘+‘等符号给工厂就可以生成相应的实例, 然后客户端直接做运算就好了.

但是同样的, 他还有个缺点, 就是这个工厂类本身并不容易扩展和维护, 例如现在要添加一个开方的计算, 首先从Operation继承一个开方类, 这一步没有问题, 接下来就要去给运算工厂类的方法里加‘case‘的分支条件, 这修改了原有的类, 违背了我们的"开放-封闭原则", 于是, 工厂模式就来了...

工厂模式: 定义一个用于创建对象的接口, 让子类决定实例化哪一个类, 工厂方法使一个类的实例化延迟到其子类.

#include <iostream>
using namespace std;

class Operation {
public:
    virtual double GetResult() = 0;

    double m_dNum_A = 0;
    double m_dNum_B = 0;
};

class OperationAdd : public Operation {
public:
    virtual double GetResult() {
        double dResult = m_dNum_A + m_dNum_B;
        return dResult;
    }
};

class OperationSub : public Operation {
public:
    virtual double GetResult() {
        double dResult = m_dNum_A - m_dNum_B;
        return dResult;
    }
};

class OperationMul : public Operation {
public:
    virtual double GetResult() {
        double dResult = m_dNum_A * m_dNum_B;
        return dResult;
    }
};

class OperationDiv : public Operation {
public:
    virtual double GetResult() {
        double dResult = m_dNum_A / m_dNum_B;
        return dResult;
    }
};

class IFactory {
public:
    virtual Operation* CreateOperate() = 0;
};

class AddFactory
    : public IFactory {
public:
    Operation* CreateOperate() {
        return new OperationAdd();
    }
};

class SubFactory
    : public IFactory {
public:
    Operation* CreateOperate() {
        return new OperationSub();
    }
};

class MulFactory
    : public IFactory {
public:
    Operation* CreateOperate() {
        return new OperationMul();
    }
};

class DivFactory
    : public IFactory {
public:
    Operation* CreateOperate() {
        return new OperationDiv();
    }
};

int _tmain(int argc, _TCHAR* argv[]) {
    IFactory* operFactory = NULL;
    char cOp;
    cout << "请输入操作符(+ - * / . . .):" << endl;
    cin >> cOp;

    switch (cOp) {
    case ‘+‘:
        operFactory = new AddFactory();
        break;
    case ‘-‘:
        operFactory = new SubFactory();
        break;
    case ‘*‘:
        operFactory = new MulFactory();
        break;
    case ‘/‘:
        operFactory = new DivFactory();
        break;
    }

    if (operFactory != NULL) {
        Operation* pOper = operFactory->CreateOperate();
        cout << "请输入第一个数:" << endl;
        cin >> pOper->m_dNum_A;
        cout << "请输入第二个数:" << endl;
        cin >> pOper->m_dNum_B;

        try {
            double dResult = pOper->GetResult();
            cout << "结果是: " << dResult << endl;
        } catch (...) {
            cout << "请输入正确操作数" << endl;
        }
    }

    system("PAUSE");
    return 0;
}

这是我用C++模拟出来的工厂模式, 这个例子虽然实现出了工厂模式, 它将选择判断的问题丢给了客户端, 使得客户端维护起来变得麻烦, 如果要添加新运算,  本来是改工厂类, 而现在是改客户端, 看起来好像变得更麻烦了, 那为什么还要用工厂模式呢?

那到底什么时候该用工厂模式呢?

来看<大话设计模式>中雷锋的例子, 现在有个雷锋类, 它有扫地, 洗衣, 买米三个方法, 现在有三个快毕业的大学生要学习雷锋做好事, 于是他们就要继承雷锋那个类, 这里一开始用简单工厂模式, 有个简单的"雷锋工厂" -- SimpleFactory, 通过传入的参数来实例化对象. 因为学习雷锋出来学生外还是社会志愿者, 所以这个简单工厂类可能像下面这样:

再来看客户端代码:

好, 现在需求来了,  这三个学生毕业了, 他们从大学生编程了社区志愿者, 我们需要改原码, 把三名创建"学雷锋的大学生"换成"社区志愿者", 我们需要改动三个地方. 那么就里就会出现重复的操作, 如果改成工厂模式来实现:

再来看客户端代码:

此时, 如果我们换成"社区志愿者", 只要修改第一句代码就可以了.

写在最后:

其实什么时候用简单工厂, 什么时候用工厂, 我还没完全弄明白, 下面这段摘自网上的分析:

工厂方法模式是为了克服简单工厂模式的缺点(主要是为了满足OCP)而设计出来的。但是,工厂方法模式就一定比简单工厂模式好呢?笔者的答案是不一定。下面笔者将详细比较两种模式。

  1. 结构复杂度 从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。
  2. 代码复杂度 代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。
  3. 客户端编程难度 工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优点。
  4. 管理上的难度 这是个关键的问题。 我 们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同 样具备良好的扩展性——扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但笔者认为不需要太拘 泥于设计理论,要知道,sun提供的java官方工具包中也有想到多没有满足OCP的例子啊(java.util.Calendar这个抽象类就不满足 OCP,具体原因大家可以分析下)。

    然后我们从维护性的角度分析下。首先是工厂模式, 假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时 需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式 仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。

    由以上的分析,笔者认为简单工厂模式更好用更方便些。当然这只是笔者的个人看法而已,毕竟公认的,工厂方法模式比简单工厂模式更“先进”。但有时过于先进的东西未必适合自己,这个见仁见智吧。

时间: 2024-08-10 14:08:01

9、[C++]工厂模式的相关文章

抽象工厂模式

思考:工厂方法模式:http://www.cnblogs.com/maggiejyt/p/7561253.html 工厂方法模式UML: 问题:如果这家工厂不止要生产Ball(球),还要还有Sneakers(球鞋)等 则UML图为 当Product有多种类时则是抽象工厂模式 代码(Ball的代码见简单工厂模式:http://www.cnblogs.com/maggiejyt/p/7561253.html) Sneakers(球鞋抽象类) package com.maggie.FactoryMet

设计模式 2/23 工厂模式

工厂模式是最常用的设计模式之一,用好了,代码优雅,可维护性高,对系统设计会上一个台阶 为什么这么说,因为工厂模式可以牵扯出抽象工厂模式,也有大家都会聊到的简单工厂模式 我们要了解一点,23中设计模式中,不包含简单工厂模式,之所以大家会去聊这个,四个字,渐进明细 通过对简单工厂模式的了解,我们引入工厂这个词,不然一个写代码的,天天给他讲工厂,工厂,工厂,西厂,东厂,会晕 同时,通过逐步的深入,从简单工厂,到工厂模式,再到抽象工厂,渐进明细的过程,逐步深入的理解,比较优劣,择优而为我们所用. 试想我

简单工厂模式

目前正在看<大话设计模式>,写此系列的文章记录下学习的经过. 简单工厂模式 先看如下代码,使用面向对象的原理实现计算器功能 Operation运算类 1 public class Operation 2 { 3 private double numberA = 0; 4 private double numberB = 0; 5 6 public double NumberA 7 { 8 get { return numberA; } 9 set { numberA = value; } 10

设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)

本文主要对设计模式进行大概解说.特别是对工厂模式进行简明的解析: 一.设计模式的分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.訪问者模式.中介者模式.解释器模式. 事实上还有两类:并发型模式和线程池模式. 二.设计模式的六大原则 1.开闭原则(Op

工厂模式

工厂模式属于创建型模式,由一个工厂对象决定创建出哪一种产品类的实例. 角色: IProduct: 产品共同的接口 Product1:具体的产品类 Creator:工厂类,可根据参数决定创建的产品类型 示例: public interface IProduct { void myfunction(); } --- class Product1 implements IProduct{ public void myfunction(){ System.out.println("function1&q

Java设计模式—工厂方法模式&amp;抽象工厂模式

工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义:Creator为抽象创建 类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的. 工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码: 抽象产品类: pub

java设计模式--工厂模式

总结 (1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的. (2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成. (3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类.它针对的是有多个产品的等级结构.而工厂方法模式针对的是一个产品的等级结构. 一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java

大话设计模式:简单工厂模式

由于面向过程编程造成的代码膨胀问题越来越严重,使其维护的代价高,灵活性很低.为了使代码易维护.易扩展.易复用和灵活性好,所以我们在采用面向对象编程的时候,防止采用面向对象的语言实际上却做着面向过程的事儿,更需要采用某种设计模式,核心就是使程序变得高内聚,低耦合,这样的程序才能达到上面的四个优点.而简单工厂模式的出现也正是为了达到这样一种效果,将工厂和产品分块,具体解决了实例化那个对象(具体产品)的需求.从而实现了高内聚,低耦合.使程序易维护.易扩展.易复用和灵活性好.同时也用到了面向对象编程的三

大话设计模式:抽象工厂模式

抽象方法模式:提供一个创建一系列相关或互相依赖对象的接口,而无需指定他们具体的类. 三种模式的对比:   简单工厂模式 工厂模式 抽象工厂模式 产品 可以有多个但是都属于同一类, 同一等级.都继承产品抽象类. 可以有多个但是都属于同一类,同一等级. 都继承产品抽象类. 可以有不同种类的产品,每类有多中 具体产品: 抽象产品 只能有一个 只能有一个; 多个抽象产品类:每个抽象产品类可 以派生多种具体产品: 抽象工厂类   只能有一个,可以派生出多个具体工厂类: 只有一个,可派生出多个具体工厂类:

【设计模式】1、抽象工厂模式

对于这个抽象工厂的相应的代码实现 /** * 功能:抽象工厂模式的作用 适用性 1.一个系统要独立于它的产品的创建.组合和表示时. 2.一个系统要由多个产品系列中的一个来配置时. 3.当你要强调一系列相关的产品对象的设计以便进行联合使用时. 4.当你提供一个产品类库,而只想显示它们的接口而不是实现时. * 时间:2016年2月11日22:18 * 作者:cutter_point */ package com.shejimoshi.create.AbstractFactory; public in