cpp学习设计模式:工厂方法模式


在学习工厂方法模式之前,先回忆前面学的简单工厂模式;

简单工厂模式就是将对象的创建和逻辑的判断都交给了一个工厂类去做,这样做的优点是客户端不需要知道具体产品类的类名和具体产品的生产过程,达到分离的目的;

但是简单工厂模式的缺点也是不容忽略的,那就是工厂类的责任太过重大,而且如果产品类比较多的话,判断逻辑也会比较复杂,使系统的逻辑变得难理解;

上面是对简单工厂模式的回忆;那么和我们现在要学习的工厂方法模式有什么关系呢?

工厂方法模式是属于GoF23种模式中的一种,它是基于简单工厂模式的设计模式,不过不同的是,工厂方法模式继承了简单工厂方法的优点,同时也没有简单工厂方法的缺点,即造成工厂类的复杂逻辑;而且如果要添加新的产品类的话,就不得不去修改工厂类的逻辑,违背了开闭原则,这是 我们不希望看到的;

那么,工厂方法模式到底是怎么做到这点的呢,下面我们先来看看工厂方法模式的定义;


工厂方法模式:工厂方法模式又称为工厂模式,也叫虚拟构造器模式或者多态工厂模式(当然,这里是Java的多态,和C++还是有区别的),它属于创建型模式;在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生产具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟该实例化哪一个具体产品类;

Java和C++多态实现上的区别

画张图,可以更直观的看出工厂方法模式和简单工厂模式的区别;

如果可以忽略画的图比较丑的话,我觉得还是能明显的看出,工厂方法和简单工厂方法的最大不同之处:将责任重大的工厂类,即简单工厂模式只有一个工厂类,解放出来,进而变为多个工厂子类,将具体产品的生产交给具体的工厂,而如果要添加新的产品类的话,只需要再添加一个新的工厂来服务即可,不再修改工厂逻辑;

看到这,肯定有很多人很疑惑了,那么具体的工厂子类是如何选择的?即如果没有了简单工厂模式那样的复杂逻辑判断,该如何决定具体产品生产的工厂呢? (我昨晚也琢磨了好一会);

这个就是工厂模式屏蔽简单工厂模式的巧妙之处,说巧妙吧其实也不巧妙,嘿嘿;

举个例子:我现在有一个车间(抽象工厂基类),有四条生产线(工厂子类),分别生产四种品牌的电视(产品对象类),但是此时动力机器只有一台,即每次只能运作一台生产线,而决定运作那一条生产线的要素在于,启动机器的钥匙,钥匙有四把,也分别对应四种品牌的电视,需要生产哪一种品牌的电视只需要插入对应的钥匙即可,机器就会运转对应的生产线; 那么这个钥匙就很关键; 说简单那点,其实就是提前将生产线确定了,并且一次只能运转一条生产线,如果现在运转的是Hair, 你想要LOL电视的产品的话,就需要拔出Hair的钥匙,插入LOL的钥匙,将选择权抽象了出来,而不是再通过简单的逻辑判断;

其它的地方都很好理解,烦的就是这个钥匙,到底是什么,在《设计模式》这本书上,采用的是Java 的两个机制XML文档的配置文件,在这个文档中写入子工厂的类名;接着利用DOM机制操纵XML文档,读取到这个字符串,产生出这个类的具体对象; 这就是Java的反射机制;

简而言之,有一个文档专门存放需要的子工厂的类名(就是钥匙),而有专门的方法可以拿到这个类名,进而产生一个实例; 这样就不需要进行什么逻辑判断,是Hair还是LoL之类的; 但是每次只能运作一个产品对象的生产,修改的是这个XML文档,而不会去修改工厂类,这符合了开闭原则;

由于Java比较渣,又想不到用C++合适的方法来模式这个对XML文档操作的模拟,真的是有点无奈;

这是Java实现反射机制的关键代码:即通过类名来生成实例对象并返回

//code = Java
Class c = Class.forName("String");
Object obj = c.newInstance();
return obj;

下面用C++ 伪代码来简单实现:

#include<iostream>using namespace std;class TV
{
public://纯虚函数,抽象基类,公共方法;virtual void play() = 0;virtual ~TV()    //注意将基类的析构函数设为虚函数{cout<<"~TV"<<endl;}
};class Hair:public TV
{
public:void play(){cout<<"Hair tv working!"<<endl;}~Hair()  {cout<<"~Hair"<<endl;}
};class TCL:public TV
{
public:void play(){cout<<"TCL tv working!"<<endl;}~TCL()  {cout<<"~TCL"<<endl;}
};class BaseFactory
{
public://纯虚函数,抽象类;virtual TV* product() = 0;virtual ~BaseFactory()    //注意将基类的析构函数设为虚函数{cout<<"~BaseFactory"<<endl;}
};class SonHairFactory:public BaseFactory
{
public:TV* product(){//Hair子工厂返回Hair产品对象;//这里其实最好使用智能指针来维护这个对象,因为C++没有Java的垃圾回收机制//容易造成内存泄漏;cout<<"Hair tv being producted!"<<endl;return new Hair();}~SonHairFactory()  {cout<<"~SonHairFactory"<<endl;}};class SonTCLFactory:BaseFactory
{
public:TV* product(){cout<<"TCL tv being producted!"<<endl;return new TCL();}~SonTCLFactory()  {cout<<"~SonTCLFactory"<<endl;}
};//我们直接以main函数来模拟客户端;int main()
{//注意,C++千万不要写成TV tv,会被笑的,抽象基类不可以不实例化;TV* tv;BaseFactory* factory;//factory = ("Java反射机制得到的子工厂队形");//C++的话现在只能将子工厂类名暴露出来了factory = new SonHairFactory();tv = factory->product();    //生产的对象传给tv指针,Java的话直接是对象;tv->play(); //释放空间; Java不需要,有垃圾回收机制;delete(tv);delete(factory);system("pause");return 0;
}

测试结果

实现的过程大概描述出来,就是没有Java的反射机制,在后面如果找到合适的方法,我再来替换;不过重点是理解工厂方法模式的思想;


工厂方法模式的优点

  1. 基本具有简单工厂模式的优点,不再赘述;
  2. 添加新产品时不需要修改工厂类,符合开闭原则,就是弥补了简单工厂模式的缺点;

工厂方法模式的缺点

  1. 添加新产品时需要添加对应的产品类和子工厂类比较麻烦,还有就是产品比较多的时候,类泛滥的问题;
  2. 使用反射机制,需要进行抽象层,就是增加了系统的实现难度;
  3. 单一的执行,每次只能单一的执行一种产品的生产;生产下一种产品需要对XML文档进行修改,我们这里C++的话就是每次需要替换子工厂类名;

小结

因为语言机制的不够了解,导致模拟的不够完全,同时对工厂方法模式理解的不够通彻,希望在下一节学习抽象工厂模式的时候,会对工厂方法模式有一个更完整的理解!

【设计模式学习】工厂方法模式相关推荐

  1. python类是实例的工厂_Python设计模式之工厂方法模式实例详解

    本文实例讲述了Python设计模式之工厂方法模式.分享给大家供大家参考,具体如下: 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类, ...

  2. 工厂方法模式--结合具体例子学习工厂方法模式

    在学习工厂方法模式之前,可以先学习一下简单工厂模式,网址是http://blog.csdn.net/u012116457/article/details/21650421,这里仍以水果的实例讲解. 先 ...

  3. 设计模式复习-工厂方法模式

     设计模式复习-工厂方法模式 相对于简单工厂,工厂方法是把算法类的实例化延迟到了调用者那去做,调用者根据自己的需要,自己实例化相关的工厂并且生产相关算法.这么做是因为简单工厂是不满足OCP的,因为如果 ...

  4. C#设计模式(3)——工厂方法模式

    一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是--简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...

  5. 设计模式之工厂方法模式(创建型)

    一.模式定义 工厂方法模式:又称工厂模式,也叫虚拟构造器模式,属于构建型设计模式,工厂方法模式是在简单工厂模式上进行拓展,生产产品的过程由具体工厂类实现,基类只实现接口,这使得工厂方法模式可以在不修改 ...

  6. 设计模式之工厂方法模式应用例题

    设计模式之工厂方法模式应用例题 题目描述 类结构图及相关说明 程序代码 运行结果 题目描述 现需要设计一个程序来读取多种不同类型的图片格式,针对每一种图片格式都设计一个图片读取器(ImageReade ...

  7. 设计模式:工厂方法模式(Factory method)

    设计模式:工厂方法模式(Factory method) 一.问题 在前一章中通过披萨的实例介绍了简单工厂模式.在披萨实例中,如果我想根据地域的不同生产出不同口味的披萨,如纽约口味披萨,芝加哥口味披萨. ...

  8. 【设计模式】工厂方法模式(C#)

    [设计模式]工厂方法模式 1.概述 针对简单工厂中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则. 定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象.工厂方法使一个产品类的实例化 ...

  9. 一文叫你弄懂Java设计模式之工厂方法模式:图解+日志记录器代码实例

    文章目录 详解Java设计模式之工厂方法模式 案例引入工厂方法模式 工厂方法模式 定义 案例分析 UML类图分析 代码分析 工厂方法的重载 工厂方法的隐藏 模式优点 模式缺点 模式适用环境 详解Jav ...

  10. 设计模式之工厂方法模式学习笔记

    定义 定义一个用于创建对象的接口,让子类去决定是实现哪个类.工厂方法使类的实例化,延迟到了子类. 结构图 角色拆解分析: 1.Product:抽象产品类 2.ConcrereProduct:具体产品类 ...

最新文章

  1. NeHe教程Qt实现——lesson01
  2. cesium js 路径_Cesium开发学习路径
  3. Data truncation: Data truncated for column/Data too long for column
  4. H - Message Bomb Gym - 102798H
  5. 服务器内存会显示ecc么,服务器内存ecc
  6. java php 女生数量,萌妹子告诉你php和java如何选
  7. jQuery自动加载更多程序
  8. max转obj_工程动画制作 | Max插件Multiscatter进阶教程
  9. 连麦互动技术及其连麦调研
  10. 如何快速出机械工程图
  11. 威纶通触摸屏与仪表通讯_威纶通触摸屏与英威腾变频器通信详细说明
  12. mw150um 驱动程序win10_Intel网卡驱动Win10专版 64位
  13. 剑指offer之编程是一种习惯
  14. PostgresSQL 使用实践
  15. app做好后如何上线_自己开发一个APP,如何上线
  16. Github上8个很棒的React项目
  17. python线性回归预测pm2.5_基于随机森林算法的PM2.5预测
  18. sklearn使用入门
  19. 在excel图表上添加数据标签
  20. 十一长假不能错过的几款开源 Linux 游戏

热门文章

  1. 【观察】神州数码:向云转型再提速,技术创新再发力
  2. 攻略:苹果手机投屏电脑 iPhone镜像投屏怎么操作
  3. 分布式医疗大数据存储方案研究综述
  4. 深圳首辆数字人民币主题观光巴士亮相
  5. docker部署seaweedf
  6. 工具之DBeaver安装及使用
  7. win7下通过easyBCD引导安装Ubuntu14.04(补充完善版)
  8. 亚马逊测评系统软件搭建教程:luminati+候鸟防关联浏览器环境
  9. python绘制缓和曲线_autocad绘制缓和曲线
  10. 在java中如何输入_java如何输入