C++设计模式之二 AbstractFactory模式

设计模式的目的就是尽量减少“变化”对程序的影响,尤其是对客户程序的影响。AbstractFactory模式作为创建型模式的一种,解决的就是“new”在变化中可能引起的问题。

先来看看new有何种不好,举个创建汽车的车门的例子:
很自然的一种想法是:Door *door = new Door();
但是如果遇到创建老爷车的车门,创建现代车的车门,这段代码就无所适从了。

OO为我们提供了哪些精华的思想?“封装”,是的,将车门的创建封装起来,于是我们有了静态工厂方法: 
客户程序代码:

1Door* door = doorFactory->CreateDoor();

库程序代码:

1class DoorFactory
2{
3public:
4  Door* CreateDoor()
5  {
6    return new Door();
7  }

8}

客户程序在此是不会变化的,不管你是老爷车门,现代车门,还是钻石车门,这些和客户程序代码都是没关系的,究竟CreateDoor出来如何结果都交给多态来判断,我们不用操心。
但是库程序代码还是需要更改的,但我们已经将“变化”与客户程序隔离了。


需求又有变化了,不光要创建车门,还需要创建引擎,车灯,而且还是不同风格的。
这时候静态工厂已经应付不来了,静态工厂有其自身的缺陷“不能应对不同系列对象”的变化。

动机:
软件系统中,经常面临“一系列相互依赖的对象”的创建工作。(两个特征:“一系列”,“相互依赖”)
将创建过程封装起来,避免“客户程序”和“多系列具体对象的创建工作”的紧耦合。

意图:
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定他们具体的类。(GoF23)

思路:


对于客户程序来说,只依赖于三个抽象的类:AbstractFactory,AbstractProductA,AbstractProductB。
以下是客户程序代码:

 1class CarManager
 2{
 3protected:
 4    AbstractFactory *abstractFactory;
 5public:
 6    //创造Car
 7    void createCar(AbstractFactory *abstractFactory)
 8    {
 9        abstractFactory->CreateEngine();
10        abstractFactory->CreateDoor();
11        abstractFactory->CreateLight();
12    }

13    //其他的操作
14    void run(){}
15}
;
16
17int _tmain(int argc, _TCHAR* argv[])
18{
19    CarManager *carManager = new CarManager();
20    //创建Classic风格的汽车
21    carManager->createCar(new ClassicFactory());
22
23    return 0;
24}

所有关于创建的操作都是用抽象类完成的,对于具体是何种类型的对象由多态实现,以此来使“客户代码”和“多系列具体对象的创建工作”达到松耦合。

如果遇到还需要扩展其他风格的汽车,可以按下图的思路

红色的部分对应新风格的车辆,只需在库程序中添加ConcreteFactory3,ProductA3,ProductB3三个类,而对于客户代码CarManager来说完全不受影响。

总结:
AbstractFactory模式有以下三个要点:
1.应对的问题是“多风格的系列对象创建”的变化问题,“系列对象”指的是这些对象之间有相互依赖或者相互作用的关系。否则使用“静态工厂”足以。
2.抽象工厂和静态工厂的核心是“封装”,将对象的创建进行封装,避免“new”引起的问题
3.抽象工程的另一个核心是“多态”,通过动态绑定来处理“不同风格”的问题

注:
AbstractFactory模式主要针对“风格”的变化,如果“对象”本身经常变化,那么该模式并不适用。


自己做的示例代码,仅供参考

  1//
  2// AbstractFactoryTest for AbstractFactory Pattern Test
  3//
  4//
  5
  6#include "stdafx.h"
  7#include "iostream"
  8using namespace std;
  9
 10//Engine,Door,Light are the Abstract Product
 11//这三个类对应UML图中的AbstractProduct类
 12class Engine
 13{
 14public:
 15    Engine()
 16    {
 17        cout<<"Abstract Engine Create"<<endl;
 18    }

 19    virtual void doSomething() = 0;
 20}
;
 21
 22class Door
 23{
 24public:
 25    Door()
 26    {
 27        cout<<"Abstract Door Create"<<endl;
 28    }

 29    virtual void doSomething() = 0;
 30}
;
 31
 32class Light
 33{
 34public:
 35    Light()
 36    {
 37        cout<<"Abstract Light Create"<<endl;
 38    }

 39    virtual void doSomething() = 0;
 40}
;
 41
 42//Abstract Factory
 43class AbstractFactory
 44{
 45public:
 46    AbstractFactory()
 47    {
 48        cout<<"AbstractFactory Create"<<endl;
 49    }

 50    virtual Engine* CreateEngine() = 0;
 51    virtual Door* CreateDoor() = 0;
 52    virtual Light* CreateLight() = 0;
 53}
;
 54
 55//SpeedEngine,SpeedDoor,SpeedLight are the Products of Speed Style 
 56//这三个类对应UML图中的ProductA1,ProductB1,ProductC1类
 57class SpeedEngine:public Engine
 58{
 59public :
 60    SpeedEngine()
 61    {
 62        cout<<"Speed Engine Create"<<endl;
 63    }

 64    void doSomething(){    }
 65}
;
 66
 67class SpeedDoor:public Door
 68{
 69public :
 70    SpeedDoor()
 71    {
 72        cout<<"Speed Door Create"<<endl;
 73    }

 74    void doSomething(){    }
 75}
;
 76
 77class SpeedLight:public Light
 78{
 79public :
 80    SpeedLight()
 81    {
 82        cout<<"Speed Light Create"<<endl;
 83    }

 84    void doSomething(){    }
 85}
;
 86
 87//classicEngine,classicDoor,classicLight are the products of Classic style
 88//这三个类对应UML图中的ProductA2,ProductB2,ProductC2类
 89class ClassicEngine:public Engine
 90{
 91public :
 92    ClassicEngine()
 93    {
 94        cout<<"Classic Engine Create"<<endl;
 95    }

 96    void doSomething(){    }
 97}
;
 98
 99class ClassicDoor:public Door
100{
101public :
102    ClassicDoor()
103    {
104        cout<<"Classic Door Create"<<endl;
105    }

106    void doSomething(){    }
107}
;
108
109class ClassicLight:public Light
110{
111public :
112    ClassicLight()
113    {
114        cout<<"Classic Light Create"<<endl;
115    }

116    void doSomething(){    }
117}
;
118
119//Factory for Speed Cars
120//对应UML图中的ConcreteFactory1类
121class SpeedFactory:public AbstractFactory
122{
123public:
124    SpeedFactory()
125    {
126        cout<<"SpeedFactory Create"<<endl;
127    }

128    virtual Engine* CreateEngine()
129    {
130        return new SpeedEngine();
131    }

132    virtual Door* CreateDoor() 
133    {
134        return new SpeedDoor();
135    }

136    virtual Light* CreateLight()
137    {
138        return new SpeedLight();
139    }

140}
;
141
142//Factory for classic Cars
143//对应UML图中的ConcreteFactory2类
144class ClassicFactory:public AbstractFactory
145{
146public:
147    ClassicFactory()
148    {
149        cout<<"ClassicFactory Create"<<endl;
150    }

151    virtual Engine* CreateEngine()
152    {
153        return new ClassicEngine();
154    }

155    virtual Door* CreateDoor() 
156    {
157        return new ClassicDoor();
158    }

159    virtual Light* CreateLight()
160    {
161        return new ClassicLight();
162    }

163}
;
164
165//Client Code ---- use the Abstract Factory & Abstract Product to create the car
166//this is never changed
167class CarManager
168{
169protected:
170    AbstractFactory *abstractFactory;
171public:
172    //创造Car
173    void createCar(AbstractFactory *abstractFactory)
174    {
175        abstractFactory->CreateEngine();
176        abstractFactory->CreateDoor();
177        abstractFactory->CreateLight();
178    }

179    //其他的操作
180    void run(){}
181}
;
182
183int _tmain(int argc, _TCHAR* argv[])
184{
185    CarManager *carManager = new CarManager();
186    //创建Classic风格的汽车
187    carManager->createCar(new ClassicFactory());
188
189    return 0;
190}

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

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

相关文章

改写DataCogs在MOSS列表中实现三级联动字段

项目中有需求需要实现列表中3级的字段联动。参照小熊的[分享]修复DataCogs二级联动FieldControl支持中文 &#xff0c;改造一下&#xff0c;实现了3级联动字段。另外&#xff0c;还可以实现一个列表中同时有两个&#xff0c;或两个以上互相独立的联动字段&#xff0c; 详细的字…

【转】01.Dicom 学习笔记-DICOM C-Store 消息服务

转自&#xff1a;https://www.jianshu.com/p/bab6a85d3486 引言 之前总体介绍了 DICOM 的消息服务&#xff0c;可以参考这篇博文&#xff0c;但是有关每个服务的详细信息没有讲解&#xff0c;本文就结合开源 DICOM 库 fo-dicom 详细介绍一下 C-Store 服务。 名词简介 在正式讲…

【转】02.Dicom 学习笔记-DICOM C-Find 消息服务

引言 前篇介绍了 DICOM C-Store 消息服务&#xff0c;本文结合开源 DICOM 库 fo-dicom 详细介绍一下 C-Find 服务。 C-Find 消息服务 C-Find 服务是一个查询服务&#xff0c;用于一个 DIMSE-service-user 在同等的DIMSE-service-user 上查询复合 SOP 实例的属性满足查询条件给出…

【转】03.Dicom 学习笔记-DICOM C-Get 消息服务

转自&#xff1a;https://www.jianshu.com/p/c7f5b9fa597c 引言 前篇介绍了 DICOM C-Find 消息服务&#xff0c;本文结合开源 DICOM 库 fo-dicom 详细介绍一下 C-Get 服务。 C-Get 消息服务 C-Get 服务主要用于获取影像&#xff0c;用于一个 DIMSE-service-user 在同等的DIMSE…

php dao类设计,DAO数据访问对象设计 - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架...

关于DAO数据访问对象设计其实是关于GoFrame框架工程化实践中比较重要一块设计。DAO设计结合GoFrame的ORM组件性能和易用性都很强&#xff0c;可以极大提高开发和维护效率。看完本章节内容之后&#xff0c;小伙伴们应该能够理解并体会到使用DAO数据库访问对象设计的优点。一、现…

再谈“我是怎么招聘程序员的”

我以前写过一篇“我是怎么招聘程序员的”的文章&#xff08;在CSDN那里有很多人进行了回复&#xff09;。今天&#xff0c;我想再谈谈关于招聘和面试这方面的东西&#xff0c;主要是以下这些原因&#xff1a; 近半年来我在进行了大量的招聘工作&#xff0c;对面试有一些新的体…

【转】04.Dicom 学习笔记-DICOM C-Move 消息服务

引言 前篇介绍了 DICOM C-Get 消息服务&#xff0c;本文结合开源 DICOM 库 fo-dicom 详细介绍一下 C-Move 服务。 C-Move 消息服务 C-Move 服务可以用来获取影像和转存影像&#xff0c;用于一个 DIMSE-service-user 在同等的 DIMSE-service-user 上查询复合 SOP 实例的属性满足…

【转】05.Dicom 学习笔记-DICOM C-Echo 消息服务

引言 经过前面几篇的介绍&#xff0c;DIMSE-C 消息服务这块已经讲解了差不多了&#xff0c;还剩最后一个 C-Echo 消息服务&#xff0c;这个服务相对前面的4个服务来说更简单一些&#xff0c;本文结合开源 DICOM 库 fo-dicom 详细介绍一下 C-Echo 服务。 C-Echo 消息服务 首先来…

哪些设计模式最值得学习

最近又在首页看到几篇设计模式相关的学习随笔。回想起来&#xff0c;这几年在园子里发布的有关设计模式的随笔都有一个共同的特点。那就是Factory和Singleton居多&#xff0c;如果是系列的&#xff0c;也往往是从这两个模式开始的。由于能够坚持把《设计模式》中所有模式都写完…

【转】000.DICOM:DICOM标准学习路线图(初稿)!!!!!!!!!!!!

转自&#xff1a;https://zssure.blog.csdn.net/article/details/49231303 题记&#xff1a; DICOM医学图像处理专栏撰写已有两个年头&#xff0c;积累了近百篇文章。 起初 只是用于记录自己科研、工作中遇到的疑难问题&#xff0c;专注于图像处理&#xff08;主要是医学图像…

对比 SQL Server 2005 和 Oracle

在 Microsoft Windows Server 上运行的 SQL Server 2005&#xff0c;为企业级关系数据库和分析解决方案提供了一个平台&#xff0c;在安全、可用性、与 Visual Studio 的整合度&#xff0c;从小企业到大企业的可扩展性以及低费用方面胜过了Oracle 10g。探索下列信息以发现在 这…

【转】pacs定位线_C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法

转自&#xff1a;https://www.cnblogs.com/Uncle-Joker/p/13686618.html 1.定位线概念&#xff1a;某个方位的影像在另一个方向的影像上的投影相交线&#xff0c;例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线。 举个例子&#xff1a;右边的是MR(核磁共…

C++设计模式之 简单工厂模式讲解(历史上最简单明白的例子)

工作之余&#xff0c;在看资料过程中发现一个极易理解的简单工厂模式的例子&#xff0c;自己亲自试练一番,感觉对这个设计模式不熟悉的朋友&#xff0c; 一看马上就知道是什么回事了。 简单工厂模式根据提供给它的数据&#xff0c;返回几个可能类中的一个类的实例。通常它返的…

【转】.NET Core 可移植类库PCL Portable Class Library详解

转自&#xff1a;https://www.kaifaxueyuan.com/server/dotnet-core/dotnet-core-portable-class-library.html 在这一章中&#xff0c;我们将讨论什么是PCL (可移植类库)&#xff0c;以及为什么我们需要PCL。为了理解这个概念&#xff0c;让我们打开上一章创建的类库项目文件夹…

设计模式C++实现(4)——原型模式、模板方法模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

【转】医疗业务学习笔记--DICOM协议的基础内容!!!!!!!!!!

转自&#xff1a;医疗业务学习笔记--DICOM协议的基础内容 - 知乎 本文首发于“雨夜随笔”公众号&#xff0c;欢迎关注。 DICOM协议是医疗领域对如何处理、存储、打印和传输医疗图片的一系列标准。DICOM是 Digital Imaging and Communications in Medicine 的缩写&#xff0c;…

linux去掉u盘写保护,最全面win10系统下u盘写保护怎么去掉

U盘写保护就是只能读取U盘中的内容&#xff0c;但是却不能修改或者将其它文件保存在U盘&#xff0c;有时候U盘写保护妨碍我们使用&#xff0c;有些朋友想要将其接除&#xff0c;对此&#xff0c;我给大家整理了win10移除写保护的方法&#xff0c;希望能帮助到你U盘是通过USB接口…

设计模式C++实现(5)——桥接模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

【转】CT基本概念(必须掌握)!!!!!!!!!!!!!!

转自&#xff1a;http://www.bmecn.com/wenku/knowledge/988.html 1.像素&#xff08;Pixel&#xff09;和体素&#xff08;Voxel&#xff09; 像素&#xff08;Pixel&#xff09;是构成图像的基本单位&#xff0c;即图像可被分解成的最小的独立信息单元。因为图像是二维的&a…

推荐笔记本用户使用的硬盘。。。2.5”战胜台式机硬盘 日立7K320-250GB

2.5”战胜台式机硬盘 日立7K320-250GB 相关评测文章参考&#xff1a;http://www.beareyes.com.cn/2/lib/200808/07/20080807034_8.htm 转载于:https://www.cnblogs.com/bingdongli/archive/2008/10/05/1304169.html