(转)工厂方法模式

转自:http://www.jellythink.com/archives/62

问题描述

之前讲到了C++设计模式——简单工厂模式,由于简单工厂模式的局限性,比如:工厂现在能生产ProductA、ProductB和ProductC三种产品了,此时,需要增加生产ProductD产品;那么,首先是不是需要在产品枚举类型中添加新的产品类型标识,然后,修改Factory类中的switch结构代码。是的,这种对代码的修改,对原有代码的改动量较大,易产生编码上的错误(虽然很简单,如果工程大了,出错也是在所难免的!!!)。这种对代码的修改是最原始,最野蛮的修改,本质上不能称之为对代码的扩展。同时,由于对已经存在的函数进行了修改,那么以前进行过的测试,都将是无效的,所有的测试,都将需要重新进行,所有的代码都需要进行重新覆盖。这种,增加成本,不能提高效率的事情,在公司是绝对不允许的(除非昏庸的PM)。出于种种原因,简单工厂模式,在实际项目中使用的较少。那么该怎么办?怎么办呢?需要对原有代码影响降到最小,同时能对原有功能进行扩展。

UML类图

那么今天介绍的工厂方法模式,就隆重登场了。它只是对简单工厂模式的扩展,在GOF的介绍中,它们是合并在一起的,而我则是单独分开进行讲解的,就是为了区分二者的利弊,便于大家在实际项目中进行更好的把握与应用。工厂方法模式是在简单工厂模式的基础上,对“工厂”添加了一个抽象层。将工厂共同的动作抽象出来,作为抽象类,而具体的行为由子类本身去实现,让子类去决定生产什么样的产品。

果冻想 | 一个原创文章分享网站

如图,FactoryA专心负责生产ProductA,FactoryB专心负责生产ProductB,FactoryA和FactoryB之间没有关系;如果到了后期,如果需要生产ProductC时,我们则可以创建一个FactoryC工厂类,该类专心负责生产ProductC类产品。由于FactoryA、FactoryB和FactoryC之间没有关系,当加入FactoryC加入时,对FactoryA和FactoryB的工作没有产生任何影响,那么对代码进行测试时,只需要单独对FactoryC和ProductC进行单元测试,而FactoryA和FactoryB则不用进行测试,则可省去大量无趣无味的测试工作。

适用场合

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

  1. 在设计的初期,就考虑到产品在后期会进行扩展的情况下,可以使用工厂方法模式;
  2. 产品结构较复杂的情况下,可以使用工厂方法模式;

由于使用设计模式是在详细设计时,就需要进行定夺的,所以,需要权衡多方面的因素,而不能为了使用设计模式而使用设计模式。

代码实现

/*
** FileName     : FactoryMethodPatternDemo
** Author       : Jelly Young
** Date         : 2013/11/18
** Description  : More information, please go to http://www.jellythink.com
*/#include <iostream>
using namespace std; class Product { public: virtual void Show() = 0; }; class ProductA : public Product { public: void Show() { cout<< "I'm ProductA"<<endl; } }; class ProductB : public Product { public: void Show() { cout<< "I'm ProductB"<<endl; } }; class Factory { public: virtual Product *CreateProduct() = 0; }; class FactoryA : public Factory { public: Product *CreateProduct() { return new ProductA (); } }; class FactoryB : public Factory { public: Product *CreateProduct() { return new ProductB (); } }; int main(int argc , char *argv []) { Factory *factoryA = new FactoryA (); Product *productA = factoryA->CreateProduct(); productA->Show(); Factory *factoryB = new FactoryB (); Product *productB = factoryB->CreateProduct(); productB->Show(); if (factoryA != NULL) { delete factoryA; factoryA = NULL; } if (productA != NULL) { delete productA; productA = NULL; } if (factoryB != NULL) { delete factoryB; factoryB = NULL; } if (productB != NULL) { delete productB; productB = NULL; } return 0; }

2013年11月18日 于大连、东软。

转载于:https://www.cnblogs.com/buptlyn/p/4442233.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一种父线程阻塞等待子线程的有效方法

最近在做一个查询优化时&#xff0c;考虑到一次查询耗时较多&#xff0c;所以打算用多线程来做&#xff0c;之前是串行查询。比如一个用户查询触发50个线程&#xff0c;在只有一个用户的情况下&#xff0c;性能比串行查询确实提高了许多&#xff0c;但当多个用户同时触发查询的…

C语言利用循环队列实现滑动平均值滤波器,提高计算速度

目录源码Filter.cFilter.h使用效果普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 串口示波器&#xff1a;Vofa 1.3.10 网上查到的滑动平均值滤波器在计算平均值的时候还要再for累加一遍&#xff0c;这太浪费时间了&#xff0c…

Exchange Server 2013日记功能

9.6 日记9.6.1 日记功能为什么很重要首先&#xff0c;了解日记功能与存档功能之间的区别十分重要&#xff1a;首先&#xff0c;了解日记功能与存档功能之间的区别十分重要&#xff1a; “日记”可以记录组织中的所有通信&#xff08;包括电子邮件通信&#xff09;&#xff0c;以…

VB数据库经典实例总结(二)

大家先看一张似图非图的图、 我们先称它为“过程”也许有不对的地方&#xff0c;在我学数据库到这个阶段、到这个刚刚接触、初生牛犊不怕虎的阶段对它的理解是这样的、所有的都是这个过程、只是在这中间掺杂了一些知识点&#xff08;我们要掌握的&#xff09;针对有些个别的&am…

适用于单片机的FFT快速傅里叶变换算法,51单片机都能用

目录源码FFT.cFFT.h使用方法效果其他部分的代码main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 算法来自FFT算法的使用说明与C语言版实现源码 —— 原作者&#xff1a;吉帅虎 速度更快的版本见C语言实现的FFT与IFFT源代码…

第9课 - 函数重载分析(下)

第9课 - 函数重载分析&#xff08;下&#xff09; 1. 重载与指针 1.1 下面的函数指针将保存哪个函数的地址&#xff1f; 1.2 函数重载遇上函数指针 将重载函数名赋值给函数指针时&#xff1a; &#xff08;1&#xff09;根据重载规则挑选与函数指针参数列表一致的候选者 &#…

常见窗函数的C语言实现及其形状,适用于单片机、DSP作FFT运算

目录源码WindowFunction.cWindowFunction.h使用形状三角窗巴特利特窗巴特利特-汉宁窗布莱克曼窗布莱克曼-哈里斯窗博曼窗切比雪夫窗平顶窗高斯窗海明窗汉宁窗纳托尔窗Parzen窗矩形窗&#xff08;模拟&#xff09;效果无窗汉宁窗平顶窗平台&#xff1a;Windows 10 20H2 Visual …

.net Json JavaScriptSerializer JsonHelper类

结合.net 的JavaScriptSerializer 类实现Json数据处理 调用1&#xff1a; Model.Users m BLL.UsersBLL.GetUserById(Convert.ToInt32(id));string result "";if (m ! null)result JsonHelper.ObjectToJSON(m);context.Response.Write(result); 调用2&#xff…

C语言实现的FFT与IFFT源代码,不依赖特定平台

目录源码FFT.cFFT.h使用方法初始化输入数据FFT 快速傅里叶变换解算FFT结果使用python绘制FFT波形IFFT 快速傅里叶逆变换解算IFFT结果Windows 10 20H2 Visual Studio 2015 Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on …

在51单片机上使用递归的注意事项

目录问题应对措施原理普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 问题 在Keil C51中直接使用递归会报如下警告&#xff1a; recursive call to non-reentrant function 为了提高运行效率&#xff0c;C51采用静态分配局部变量…

C盘瘦身:QQ文件的清理及Group2文件夹

目录问题解决方法Windows 10 20H2 TIM 问题 最近C盘被撑爆了 使用SpaceSniffer一扫发现QQ的文件中有个Group2文件夹占了我17G 但使用QQ自带的个人文件夹清理却扫不到&#xff0c;据说直接删除会丢失近期所有群聊的聊天图片 解决方法 在这个地方找到了大神fsz1987给出的解…

获取ArcGIS安装路径

在要素类进行符号化时&#xff0c;使用axSymbologyControl需要安装路径下的Style文件路径&#xff0c;在AE9.3VS2008中是这样的&#xff1a; Microsoft.Win32.RegistryKey regKey Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\ESRI\\CoreRuntime",…

【51单片机快速入门指南】3.2:定时器/计数器

目录快速使用硬知识传统51单片机 CPU 时序的有关知识&#xff08;12T&#xff09;51 单片机定时器原理51 单片机定时/计数器结构定时器/计数器0/1定时器/计数器0和1的相关寄存器控制寄存器工作模式寄存器工作模式模式0(13位定时器/计数器)模式1(16位定时器/计数器)模式2(8位自动…

sublime_text 3 注册序列号

为什么80%的码农都做不了架构师&#xff1f;>>> ----- BEGIN LICENSE ---- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 6C0EEB94 BC99798F 942194A6 02396E98 E62C9979 4BB979FE 91424C9D A45400BF F6747D88 2FB88078 90F5CC94 1CDC92DC 845…

【51单片机快速入门指南】3.2.1:PWM、呼吸灯与舵机

目录硬知识PWM&#xff08;脉冲宽度调制&#xff09;基本原理脉宽调制分类上机实战呼吸灯main.c中断服务函数修改TIM.c中的中断服务函数效果开发板电路分析舵机控制舵机控制方法main.c中断服务函数修改中断服务函数舵机测试程序main.c效果普中51-单核-A2 STC89C52 Keil uVisio…

Proteus仿真单片机:51单片机的仿真

目录新建工程调试在Proteus中编写程序导入Keil生成的Hex程序Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 新建工程 设置名称和路径 下一步 下一步 选择系列、控制器和编译器 双击MCU设置主频 …

Linux 命令行输入

这几天刚刚接触到Linux&#xff0c;在windows上安装的VMWare虚拟机&#xff0c;Centos7。安装什么都是贾爷和办公室的同事帮忙搞定的。 在虚拟机界面&#xff0c;按快捷键CtrlAltEnter&#xff0c;可以全屏显示Linux界面&#xff0c;再按一次则退出全屏。 如何在Linux里输入命令…

【51单片机快速入门指南】2.5:并行I/O扩展与8255A

目录硬知识单片机I/O扩展基础知识I/O接口电路的功能速度协调输出数据锁存数据总线隔离数据转换增强驱动能力单片机并行扩展总线并行扩展总线的组成80C51单片机并行扩展总线I/O编址技术可编程并行接口芯片82558255硬件逻辑结构口电路总线接口电路A组和B组控制电路中断控制电路82…

win 下 apache2.4 +tomcat7 集群

为什么80%的码农都做不了架构师&#xff1f;>>> 反正每次来做一个不熟悉的东西&#xff0c;就是各种的search ,前一次去做过一个apache的东西&#xff0c;各种蛋疼&#xff0c;各种不能用。好多的东西也是比较旧了的咯。 这次结合前辈的各种东借西拿&#xff0c;总…

Proteus仿真单片机:PIC18单片机的仿真

目录新建工程ProteusMPLAB X IDE调试Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 MPLAB X IDE v5.45 新建工程 Proteus 下一步 下一步 选择芯片、编译器 搭建实验电路 MPLAB X IDE MPLAB X IDE 新建工程 选择独有项目 选择芯片 选择编译器 配置工程名称、路…