工厂方法模式_1天1个设计模式——工厂方法模式

意图

工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。

问题

假设你正在开发一款物流管理应用。1.0版本只能支持处理卡车运输,因此大部分的代码都位于名为Truck的类中。随着业务越来越广泛,该应用需要支持处理轮船运输。但是,由于大部分的代码都在Truck类中,那么添加Ship类则需要修改全部代码。

更糟糕的是,每添加一种新的运输方式,就需要对代码进行一次大规模的修改。心力憔悴啊。

解决方案

工厂方法模式建议使用特殊的工厂方法代替对于对象构造函数的直接调用 (即使用 new运算符)。*(对象仍将通过 new运算符创建, 只是该运算符改在工厂方法中调用罢了。 )*工厂方法返回的对象通常被称作 “产品”。

我们通过在子类中重写工厂方法,来改变返回产品的类型。但是,只有当产品具有共同的接口时,子类才能返回不同类型的产品,且基类中的工厂方法还将返回类型声明为这一共有接口。

利用工厂方法,对问题提出解决方案,类图如下:

69f386349b3eb5d4bcad3ad19bed9f46.png

工厂方法模式结构

be887aff7bcb65080a898f4d492ed788.png
  • Product:所有产品的共有接口。
  • Concrete Products:具体产品,对Product接口的不同实现
  • Creator:创建者声明了返回产品对象的工厂方法。 该方法的返回对象类型必须与Product接口相匹配。注意,创建者类包含一些与产品相关的核心业务逻辑。
  • Concrete Creators:将会重写基类工厂方法, 使其返回不同类型的具体产品。

对问题的代码实现

#includeusing namespace std;// 产品接口中将声明所有具体产品都必须实现的操作。class Transport {public:~Transport(){}virtual void delivery() const = 0;//不同具体产品对此进行不同实现};// 具体产品需提供产品接口的各种实现。class Truck : public Transport{public:virtual void delivery() const{cout << "卡车:通过盒子运输" << endl;}};class Ship : public Transport {public:virtual void delivery() const{cout << "轮船:通过集装箱运输" << endl;}};// 创建者类声明的工厂方法必须返回一个产品类的对象。创建者的子类通常会提供// 该方法的实现。class Logistics {public:~Logistics(){}//基类工厂方法,返回类型声明为产品共有接口virtual Transport* createTransport() const = 0;// 请注意,创建者的主要职责并非是创建产品。其中通常会包含一些核心业务// 逻辑,这些逻辑依赖于由工厂方法返回的产品对象。子类可通过重写工厂方// 法并使其返回不同类型的产品来间接修改业务逻辑。void plan_delivery() const{//调用工厂方法创建一个产品对象Transport* tran = createTransport();//使用产品tran->delivery();delete tran;}};// 具体创建者将重写工厂方法以改变其所返回的产品类型。class RoadLogistics :public Logistics {public:virtual Transport* createTransport() const{return new Truck();}};class SeaLogistics :public Logistics {public:virtual Transport* createTransport() const {return new Ship();}};//客户端代码void ClientCode(const Logistics* log) {cout << "开始运输:";log->plan_delivery();}int main() {cout << "APP:以卡车运输" << endl;Logistics* log1 = new RoadLogistics();ClientCode(log1);cout << endl;cout << "APP:以轮船运输" << endl;Logistics* log2 = new SeaLogistics();ClientCode(log2);delete log1;delete log2;return 0;}

该模式的优缺点

优点

  • 避免创建者和具体产品之间的紧耦合
  • 符合单一职责原则。将产品创建代码放在程序的单一位置,从而使代码易于维护
  • 符合开闭原则。无需更改现有客户端代码,就可以在程序中引入新的产品类型

缺点

  • 工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。

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

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

相关文章

hadoop简介(大数据技术)

Hadoop可运行于一般的商用服务器上&#xff0c;具有高容错、高可靠性、高扩展性等特点 特别适合写一次&#xff0c;读多次的场景 适合 大规模数据 流式数据&#xff08;写一次&#xff0c;读多次&#xff09; 商用硬件&#xff08;一般硬件&#xff09; 不适合 低延时的数据访问…

session与cokkie区别

刚刚转载于:https://www.cnblogs.com/igoodful/p/9511773.html

如何创建php文件,PHP如何生成.php程序文件

前台程序不少情况下需要生成.php文件&#xff0c;诸如多用户的在线日记程序、留言簿以及自助网站程序等等&#xff0c;都不可避免地在与用户的交互中生成.php程序文件。一般的&#xff0c;所生成的.php文件内容并不复杂&#xff0c;但麻雀虽小五脏俱全&#xff0c;完整的.php文…

python 字符串比较忽略大小写的方法_python实现忽略大小写对字符串列表排序的方法...

本文实例讲述了python实现忽略大小写对字符串列表排序的方法&#xff0c;是非常实用的技巧。分享给大家供大家参考。具体分析如下&#xff1a;先来看看如下代码&#xff1a;string the stirngHas manyline InTHE fIlejb51 netlist_of_string string.split()print list_of_str…

storm简介(大数据技术)

Apache Storm简介 由 chalex 创建&#xff0c;小路依依 最后一次修改 2016-12-12 什么是Apache Storm&#xff1f; Apache Storm是一个分布式实时大数据处理系统。Storm设计用于在容错和水平可扩展方法中处理大量数据。它是一个流数据框架&#xff0c;具有最高的摄取率。虽然St…

python无法对存在交叉部分的图片进行识别_Python异常样本识别 交叉验证出现错误?...

源码&#xff1a;fromsklearn.model_selectionimportKFoldfromsklearn.metricsimportrecall_scorefoldKFold(5,shuffleFalse)recall_accs[]c_param_range[0.01,0.1,1,10,100]results_tablep...源码&#xff1a;from sklearn.model_selection import KFoldfrom sklearn.metrics …

hive简介(大数据技术)

背景和概念 Hive是一个依赖于分布式存储的查询和管理大型数据集的数据仓库。传统的非大数据行业一般都是基于表进行数据存储和管理的&#xff0c;如果由于业务扩张或者其他原因迁移到HDFS平台上&#xff0c;那么需要将传统的SQL查询语句全部翻译成Map-reduce的程序实现&#xf…

返回顶部

html代码&#xff1a; <button style"position: fixed;right: 30px;bottom:20px" id"back" onclick"back()">返回顶部</button> javascript代码&#xff1a; for(var i 0; i < 100; i){ document.write("<li>"…

php npm,php – Laravel中NPM,Composer和Bower的区别?

所以在Laravel有Composer,NPM和Bower,我知道他们都是deoendancy经理.Composer – 这似乎关注PHP依赖关系,包列表是composer.json的内容控制器.要安装软件包,您可以添加到此文件或运行php composer install< package>.NPM – 这似乎专注于JavaScript依赖,但也有一个疯狂的…

kafka简介(大数据技术)

kafka是用于构建实时数据管道和流应用程序。具有横向扩展&#xff0c;容错&#xff0c;wicked fast&#xff08;变态快&#xff09;等优点&#xff0c;并已在成千上万家公司运行。 简单说明什么是kafka Apache kafka是消息中间件的一种&#xff0c;我发现很多人不知道消息中间件…

python爬取百度贴吧中的所有邮箱_python写的百度贴吧邮箱采集(带界面)

from main_def import *importrequests,reimportdatetime,timefrom tkinter importENDheaders{"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36"}#单个帖子爬虫def…

matlab晶闸管整流电路,采用Matlab/Simulink对三相桥式全控整流电路的仿真分析

本文利用Simulink对三相桥式全控整流电路进行建模&#xff0c;对不同控制角、桥故障情况下进行了仿真分析&#xff0c;既进一步加深了三相桥式全控整流电路的理论&#xff0c;同时也为现代电力电子实验教学奠定良好的实验基础。1 电路的构成及工作特点三相桥式全控整流电路原理…

flume简介(大数据技术)

1 .背景 flume是由cloudera软件公司产出的可分布式日志收集系统&#xff0c;后与2009年被捐赠了apache软件基金会&#xff0c;为hadoop相关组件之一。尤其近几年随着flume的不断被完善以及升级版本的逐一推出&#xff0c;特别是flume-ng;同时flume内部的各种组件不断丰富&#…

vue中waiting for update signal from wds_10个vue快捷开发技巧助你成为中级前端工程师!(二)...

前言先赞再看&#xff0c;养成习惯~优雅更新props更新 prop 在业务中是很常见的需求&#xff0c;但在子组件中不允许直接修改 prop&#xff0c;因为这种做法不符合单向数据流的原则&#xff0c;在开发模式下还会报出警告。因此大多数人会通过 $emit 触发自定义事件&#xff0c;…

python开发学习笔记之六(面向对象)

面向对象引入&#xff1a; 现在有一个这样的需求&#xff1a;做汽水。 在之前的学习中&#xff0c;我们怎样处理这种类似的问题呢&#xff1f;思考一下&#xff0c;哦&#xff0c;不就是分步骤做嘛&#xff0c;把复杂的问题简单化&#xff0c;分成一个一个的步骤&#xff0c;就…

wampserver php乱码,WampServer搭建php环境可能遇到的问题

WampServer搭建php环境可能遇到的问题1.安装时报错&#xff0c;缺少 MSVCR100.dll 文件这是因为wampServer安装时用到的vc库没有更新&#xff0c;要安装更新之后再进行安装&#xff0c;因为之前安装的VC版本低了&#xff0c;才导致安装的时候提示丢失MSVCR100.dll文件。以下分别…

python总结字典集合列表_python 列表,元组,字典,集合,字符串相互转换

本文主要介绍列表&#xff0c;元组&#xff0c;字典&#xff0c;集合以及和字符串之间的相互转换。1. 列表与元组的互换# 将列表转化为元组li [1, 2, 3]t tuple(li)print(t, type(t))# 打印结果:(1, 2, 3) # 将元组转换成列表tu (1, 2, 3)li list(tu)print(li, type(li))# …

hbase简介(大数据技术)

HBase是什么? HBase是建立在Hadoop文件系统之上的分布式面向列的数据库。它是一个开源项目&#xff0c;是横向扩展的。 HBase是一个数据模型&#xff0c;类似于谷歌的大表设计&#xff0c;可以提供快速随机访问海量结构化数据。它利用了Hadoop的文件系统&#xff08;HDFS&…

NAT地址转换

2017年1月12日, 星期四NAT地址转换SNAT&#xff1a;源地址转换DNAT&#xff1a;目标地址转换null转载于:https://www.cnblogs.com/jxhd1/p/9521173.html

mysql l日志分析,MySQL的截取与分析日志文件

在处理过程中&#xff0c;对几种常用的日志截取方法进行了汇总和测试&#xff1a;截取日志段的的方法汇总与测试方式一&#xff1a; 确定时间段的行号&#xff0c;使用head和tail命令截取 搜索时间&#xff1a; Time: 151212 00:00:00 先到gg&#xff0c;到文件最前面&#xff…