工厂模式属于创建型模式,主要可分为三类,简单工厂、工厂方法、抽象工厂。工厂模式规定,无论是工厂函数,工厂类的成员函数,返回的对象都必须位于heap。

有三点需要特别注意:

  • 堆对象

    三种工厂模式都属于创建型模型,所创建的对象都位于堆内存中,需要手动释放其所占内存。

  • 基类的虚析构函数

    在Scott Meyers大师的Effective C++有专门一节论述将析构函数声明为虚析构函数的必要性。其中所举的范例即是工厂方法模式。当derived class 对象经由一个base class指针(工厂方法的create方法返回的恰是基类指针,因为它不确定创建的是哪个子类对象)删除,而该base class 带着一个non-virtual析构函数,其结果未有定义(undefined behavior)。

  • UML类图

    UML类图是把握设计模式的关键,如何将一段描述转换为UML类图,如何将UML类图转换为程序语言,是软件开发的一项基本能力。更详尽的内容请见

简单工厂模式

其主要特点是需要创建对象时,需要在工厂类中做判断(if),根据不同的条件或者前提创建不同的对象。这也就造成了,当增加新的产品时,需要修改工厂类,也就是其增加其判断分支。

一家成产处理器核的厂家(对应着一个工厂类),能够生产两种类型的处理器核。简单工厂模式要求,客户需要什么样的处理器核,务必显式地告知工厂。

先看UML类图:

这里不妨简单做个说明,虚线表示的是依赖关系(dependency),即 SingleCoreA类和 SingleCoreBFactory的类声明中会以成员函数的局部对象的形式出现,如果以成员变量的方式出现的话,就不叫依赖关系,而是关联关系了(association)。三角箭头表示的是继承关系,在UML的术语中叫泛化关系(generation)。

enum CORETYPE {COREA, COREB};
class SingleCore
{
public:virtual void show() = 0;virtual ~SingleCore();
} class SingleCoreA : public SingleCore
{
public:void show() { std::cout << "SingleCoreA::show()" << std::endl;}
}class SingleCoreB : public SingleCore
{
public:void show(){ std::cout << "SingleCoreB::show()" << std::endl;}
}class Facotry
{
public:SingleCore* createSingleCore(CORETYPE type)  {// 返回基类指针,构成一种依赖关系,dependency if (type == COREA)return new SingleCoreA;else if (type == COREB)return new SingleCoreB;elsereturn NULL;}
}int main(int, char**)
{Factory fact;SingleCore* core = fact.cretaSingleCore(COREB);//delete core;    // heap object return 0;
}

工厂方法模式

因为简单工厂将所有欲创建的子类集合在了一起,耦合度较高。当要增加新的产品类型时,需要修改工厂类,违反了开闭原则,即对扩展开放,对修改关闭,或者说,软件实体(类、模块、函数)可以扩展,但是不可修改。工厂方法(Factory Method),将创建的动作分配给不同的工厂子类,一个工厂子类对应于一个产品的创建。Factory Method使一个类的实例化的动作延迟到其子类。

class SIngleCore
{
public:virtual void show() = 0;
}class SingleCoreA :public SingleCore
{
public:void show() { std::cout << "SingleCore::show()" << std::endl;}
} class SingleCoreB: public SingleCore
{
public:void show() { std::cout << "SingleCoreB::show()" << std::endl;}
}class Factory
{
public:virtual SingleCore* createSingleCore() = 0;
}class FactoryA : public Factory
{
public:SingleCore* createSingleCore() { return new SingleCoreA;}      // 工厂子类FactoryA对应于产品子类SingleCoreA的创建
} class FactoryB : public Factory
{
public:SingleCore* createSingleCore(){ return new SingleCoreB;}      // 工厂子类FactoryB对应于产品子类SingleCoreB的创建
}int main(int, char**)
{SingleCore* core;FactoryA fa;FactoryB fb;core = fa.createSingleCore();core->show();       // 调用SingleCoreA的show()方法delete core;core = fb.createSingleCore();core->show();       // 调用SingleCoreB的show()方法dereturn 0;
}

工厂方法模式也有自己的缺点,每增加一个商品,虽然不像简单工厂,需要修改工厂类,而是需要增加一个对象的工厂。如果商品的种类有很多时,例如iPhone4S,iPhone5,iPhone5S,…,等等一系列的产品的时候。在C++的实现中,就需要定义一个个的工厂类。显然这与简单工厂模式相比,需要更多的类定义。

抽象工厂模式

抽象工厂模式,它的定义提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体的类。(不知道这样理解对不对)

class SingleCore
{
public:virtual void show() = 0;
}
class SingleCoreA:public SingleCore
{
public:void show() { std::cout << "SingleCoreA::show()" << std::endl;}
}
class SingleCoreB:public SingleCore
{
public:void show() { std::cout << "SingleCoreB::show()" << std::endl;}
}class MutliCore
{
public:virtual void show() = 0;
}
class MultiCoreA:public MultiCore
{
public:void show() { std::cout << "MultiCoreA::show()" << std::endl;}
}
class MultiCoreB:public MultiCore
{
public:void show(){ std::cout << "MultiCoreB::show()" << std::endl;}
}class CoreFactory
{
public:virtual SingleCore* createSingleCore();virtual MultiCore* createMultiCore();
}class FactoryA :public CoreFactory
{
public:SingleCore* createSingleCore() { return new SingleCoreA;}  MultiCore* createSingleCore(){ return new MultiCoreA;}
}class FactoryB :public CoreFactory
{
public:SingleCore* createSingleCore(){ return new SingleCoreB;}MultiCore* createMultiCore(){ return new MultiCoreB;}
}int main(int, char**)
{MultiCore* mcore;FactoryA fa;FactoryB fb;mcore = fa.createMultiCore();mcore->show();mcore = fb.createMultiCore();mcore->show();return 0;
}

references

  1. <设计模式C++实现(1)——工厂模式>

设计模式C++实现——工厂模式相关推荐

  1. getinstance方法详解_二、设计模式总览及工厂模式详解

    二.架构师内功心法之设计模式 2.架构师内功心法之设计模式 2.1.课程目标 1.通过对本章内容的学习,了解设计模式的由来. 2.介绍设计模式能帮我们解决哪些问题. 3.剖析工厂模式的历史由来及应用场 ...

  2. php工程模式,PHP设计模式(八):工厂模式

    Introduction 在PHP设计模式(七):设计模式分类中我们提到过创建设计模式(Creation patterns),创建设计模式专注于设计对象(Object)和实例(Instance)的创建 ...

  3. 设计模式系列·抽象工厂模式

    前言 以小说的笔法写的设计模式系列文章,你绝对看得懂![首发于公众号:"聊聊代码"] 设计模式系列·王小二需求历险记(一) 设计模式系列·王小二需求历险记(二) 设计模式系列·封装 ...

  4. 设计模式三—抽象工厂模式

    设计模式三-抽象工厂模式 一.定义 抽象工厂模式是工厂方法模式的进一步抽象.如果产品簇中只有一种产品,则退化为工厂方法模式. 二.原理图 三.代码实例 * 苹果和土豆是园丁1的杰作 * 葡萄和西红柿是 ...

  5. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页] [源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Facto ...

  6. java设计模式---三种工厂模式

    工厂模式提供创建对象的接口. 工厂模式分为三类:简单工厂模式(Simple Factory), 工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory). GOF ...

  7. 设计模式复习-抽象工厂模式

    设计模式复习-抽象工厂模式 有两种硬件,PC和Phone,有两种系统,Windows和Linux,现在假设PC和Phone上全都能安装这两个系统,并且将来硬件不会在变化,但是系统可能需要扩展,比如扩展 ...

  8. php的类图怎么生成_PHP设计模式之简单工厂模式

    PHP设计模式之简单工厂模式 先从简单工厂入门,不管是面试还是被他人面试,在问到设计模式的时候,大多数人都会提到工厂模式.毫无疑问,工厂相关的几种模式在设计模式中是最出名的也是应用比较广泛的一种模式. ...

  9. 设计模式之四(抽象工厂模式第三回合)

    原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如I ...

  10. python抽象工厂模式_Python设计模式之抽象工厂模式

    Python设计模式之抽象工厂模式 这篇文章主要为大家详细介绍了Python设计模式之抽象工厂模式,感兴趣的小伙伴们可以参考一下 python面向对象编程入门,我们需要不断学习进步 "&qu ...

最新文章

  1. 智能车技术创新与实践(01510422-90)课程简介
  2. Merge into 详细介绍
  3. 文件和参数一起上传_Spring boot的文件上传
  4. 三次握手和四次断开问题
  5. win服务器数据丢失怎么办
  6. 【媒体服务质量监控与QoE】
  7. python文件路径操作及pathlib库
  8. 优秀的云存储解决方案Dropbox,现在注册就有2G
  9. 终极解决方案UnicodeEncodeError: 'ascii' codec can't encode character u'\uff08' in position 13: ordinal not
  10. jQuery.ajax()异步方法的漏洞
  11. 一步一步教你安装Nginx+PHP+Mysql
  12. 黑马程序员-关于C语言基本运算的一些注意点
  13. c语言大学生信息管理系统实验报告,c语言学生信息管理系统实训报告
  14. 《工业设计史》第九章:职业工业设计师的出现
  15. 会声会影 html5,一文了解会声会影哪个版本比较好用
  16. 如何解除电子书DRM限制
  17. 【pyecharts | 颜色配置】关于pyecharts中自定义颜色问题详解
  18. CodeForces 711B. Chris and Magic Square(水题)
  19. Kotlin编译与Intrinsics检查
  20. udp ue4 通讯_UE4 UDP通信

热门文章

  1. 执行 Python 程序的三种方式及Python 的 IDE —— `PyCharm`
  2. Welcome to Apache HBase 介绍一
  3. Hive Managed Table与 External Table区别
  4. 性能测试指标(重要)
  5. ajax跨域请求wcf服务,jQuery ajax跨域发布到WCF休息服务
  6. Matplotlib——多图合并
  7. 【bzoj4653】[Noi2016]区间 双指针法+线段树
  8. 洛谷 1855——榨取kkksc03
  9. autoLayout+sizeClass屏幕适配
  10. 使用 WebSphere Portlet Factory 构建基于 Web2.0 的灵活 SOA 前端