设计模式C++描述----03.工厂(Factory)模式
工厂模式属于创建型模式,大致可以分为三类,简单工厂模式、工厂方法模式、抽象工厂模式。
一. 简单工厂模式
简单工厂模式,它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。举个例子,有一家电子产品生产厂家,它只有一个工厂,能够生产两种型号的产品,A 和 B。可以想像一下,A是电吹风,B是电风扇。客户需要什么样的吹风类产品,一定要显示地告诉生产工厂。
代码实现:
- enum CTYPE {PRODUCT_A, PRODUCT_B};
- //抽象产品类
- class Product
- {
- public:
- virtual void Show() = 0;
- };
- //具体产品A
- class ProductA: public Product
- {
- public:
- void Show() { cout<<"Product A"<<endl; }
- };
- //具体产品B
- class ProductB: public Product
- {
- public:
- void Show() { cout<<"Product B"<<endl; }
- };
- //唯一的工厂,可以生产两种型号的产品,在内部判断
- class Factory
- {
- public:
- Product* CreateProduct(enum CTYPE ctype)
- {
- if(ctype == PRODUCT_A) //工厂内部判断
- return new ProductA(); //生产产品A
- else if(ctype == PRODUCT_A)
- return new ProductB(); //生产产品B
- else
- return NULL;
- }
- };
- int main()
- {
- Factory fac; //工厂
- Product *pro = fac.CreateProduct(PRODUCT_A);//生产产品A
- pro->Show();
- return 0;
- }
缺点:
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
打个比方:
这个工厂在刚建厂时,就要事先把以后的要生产的产品考虑好,部门划分好。如果要生产新的产品,就要改变工厂的空间布局,部门也要重新划分,这是很不利的。当然如果工厂以后发展不大,也就是创建的对象比较少时,还是可以用的。
二. 工厂方法模式
所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
还以刚才的例子解释,这家电子厂赚了不少钱,于是决定再开设一个厂,其中一个工厂专门用来生产A型号的产品,也就是只生产电吹风,而另一工厂专门用
来生产B型号的产品,也就是只生产电风扇,这样分工明确了。以后客户要再下定单时,可以直接找到相关的工厂了,比如要A型号的产品,就找A工厂要,不再担
心下的定单是A,生产出来的是B产品了。
代码实现:
- class Product
- {
- public:
- virtual void Show() = 0;
- };
- //产品A
- class ProductA: public Product
- {
- public:
- void Show()
- {
- cout<<"Product A"<<endl;
- }
- };
- //产品B
- class ProductB: public Product
- {
- public:
- void Show()
- {
- cout<<"Product B"<<endl;
- }
- };
- //抽象工厂
- class Factory
- {
- public:
- virtual Product* CreateProduct() = 0;
- };
- //生产A的工厂
- class FactoryA: public Factory
- {
- public:
- Product* CreateProduct()
- {
- return new ProductA;
- }
- };
- //生产B的工厂
- class FactoryB: public Factory
- {
- public:
- Product* CreateProduct()
- {
- return new ProductB;
- }
- };
- int main()
- {
- Factory* fac = new FactoryA(); //A工厂
- Product* p = fac->CreateProduct(); //生产产品
- p->Show();
- return 0;
- }
其实你会发现,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,你想要加功能,本来是改工厂类的,而现在是修改客户端。
这有什么好处呢?举个例子,有三个客户原来要A产品,现在改卖B产品,在代码中体现为:
简单工厂的处理:
- Factory fac; //工厂
- Product *pro1 = fac.CreateProduct(PRODUCT_A);//生产产品A
- Product *pro2 = fac.CreateProduct(PRODUCT_A);//生产产品A
- Product *pro3 = fac.CreateProduct(PRODUCT_A);//生产产品A
- //改为B产品,这里要改三个地方
- //Product *pro1 = fac.CreateProduct(PRODUCT_B);//生产产品B
- //Product *pro2 = fac.CreateProduct(PRODUCT_B);//生产产品B
- //Product *pro3 = fac.CreateProduct(PRODUCT_B);//生产产品B
- pro1->Show();
- pro2->Show();
- pro3->Show();
工厂方法的处理:
- Factory* fac = new FactoryA(); //A工厂
- //改为B产品,这里只改一个地方
- //Factory* fac = new FactoryB(); //B工厂
- Product* pro1 = factory_A->CreateProduct(); //生产产品
- Product* pro2 = factory_A->CreateProduct(); //生产产品
- Product* pro3 = factory_A->CreateProduct(); //生产产品
- pro1->Show();
- pro2->Show();
- pro3->Show();
这里可以看到工厂方法的好处了吧,工厂方法模式是简单工厂模式的进一步抽象和推广,它集中封装了对象的创建,使得要更换产品时,不需要做大的改动就可以实现,降低了客户程序与产品对象的耦合。
优点:
相对于简单工厂模式来说,这样分工更加明确,当需要新产品时,就建一个新的工厂,而不是对原工厂类进行修改。这样做满足了"开放-封闭"原则,即可以扩展,不可修改。
缺点:
1. 每增加一种产品,就需要增加一个对象的工厂。在C++实现中,就是要定义一个个的工厂类。显然,相比简单工厂模式,工厂方法模式需要更多的类定义。
2. Factory 模式仅仅局限于一类类(就是说 Product 是一类,有一个共同的基类),如果我们要为不同类的类提供一个对象创建的接口,那就要用AbstractFactory了。
打个比方:
如果这家公司发展迅速,推出了很多新的产品,那么就要开设相应的新工厂,一种产品一个工厂。这对于客户来说是好事,分工明确了白;但对于工厂自己来说开销也变大了。
如要我想要生产核心芯片,但是芯片不是产品,不能继承于product类。因为产品和零部件,不是一类。
三. 抽象工厂模式
抽象工厂模式,它定义为提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
还以上面的例子解释,这家公司经营的还不错,针对其核心技术都申请了专利,后来生始生产相关电子芯片了
(像三星一样,即生产产品也生产芯片)。对于这种情况,我们不能在抽象产品类上继承一个零部件,因为产品和芯片没有什么共同之处,完全是两个领域。你要做
芯片,就要专心做,当成一个新的领域,不能用以前产品的那一套流程。这样划分才明确,才能更好的实现高内聚,低耦合的明标。
- //抽象产品类
- class Product
- {
- public:
- virtual void Show() = 0;
- };
- //产品A
- class ProductA: public Product
- {
- public:
- void Show()
- {
- cout<<"Product A"<<endl;
- }
- };
- //产品B
- class ProductB: public Product
- {
- public:
- void Show()
- {
- cout<<"Product B"<<endl;
- }
- };
- //抽象芯片类
- class Chip
- {
- public:
- virtual void Show() = 0;
- };
- //芯片A
- class ChipA: public Chip
- {
- public:
- void Show()
- {
- cout<<"Chip A"<<endl;
- }
- };
- //芯片B
- class ChipB: public Chip
- {
- public:
- void Show()
- {
- cout<<"Chip B"<<endl;
- }
- };
- //抽象工厂类
- class Factory
- {
- public:
- virtual Product* CreateProduct() = 0;
- virtual Chip* CreateChip() = 0;
- };
- //生产A的工厂
- class FactoryA: public Factory
- {
- public:
- Product* CreateProduct() //产品
- {
- return new ProductA;
- }
- Chip* CreateChip() //芯片
- {
- return new ChipA;
- }
- };
- //生产B的工厂
- class FactoryB: public Factory
- {
- public:
- Product* CreateProduct() //产品
- {
- return new ProductB;
- }
- Chip* CreateChip() //芯片
- {
- return new ChipB;
- }
- };
- int main()
- {
- Factory* factury = new FactoryA(); //A工厂
- Product* product = factury->CreateProduct(); //生产产品
- Chip* chip = factury->CreateChip(); //生产芯片
- product->Show();
- chip->Show();
- return 0;
- }
我们可以发现,抽象工厂比工厂模式所能处理的产品更多,最关健的是这些产品有不同的基类。
优点:
1. AbstractFactory 模式关键就是将这一组对象的创建封装到一个用于创建对象的工厂类(ConcreteFactory)中,维护这样一个工厂创建类总比维护 n 多相关对象的创建过程要简单的多。
2. 它的最大好处是易于交换产品系列,比如我要B工厂的产品,只需要在客户端代码修改一处即可。
打个比方:
这时客户只要知道A工厂是生产A类的产品和芯片的,B工厂是生产B类的,其它都不用关心,只要想要与A类相关的东东就去找A就行了。
四. 总结:
1. 简单工厂模式,所有的产品都在工厂类中进行生产。功能单一时,没有什么问题,但是当增加很多新产品时,就要不断的修改产品类,易于出错,也违反了对修改是封闭的原则。
2. 工厂方法模式,每个工厂生产一种产品,这样分工更加明确。当增加新产品时,只需增加一个工厂类,而不用修改原有工厂类,这样工厂类的耦合度就降低了。
3. 抽象工厂模式,比工厂方法模式处理的情况更多。主要是对不同产品的处理,这时的工厂能够生产多种产品,这多种产品虽然没有共同基类,但是却属于一类,具体体现在都是由同一个工厂生产。
设计模式C++描述----03.工厂(Factory)模式的更多相关文章
- Java设计模式(二) 工厂方法模式
本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...
- 设计模式-03工厂方法模式(Factory Method Pattern)
插曲.简单工厂模式(Simple Factory Pattern) 介绍工厂方法模式之前,先来做一个铺垫,了解一下简单工厂模式,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背 ...
- 设计模式(2)工厂方法模式(Factory Method)
设计模式(0)简单工厂模式 设计模式(1)单例模式(Singleton) 源码地址 0 工厂方法模式简介 0.0 工厂方法模式定义 工厂方法模式是在简单工厂模式基础上,为解决更复杂的对象创建问题而衍生 ...
- 设计模式(三)工厂方法模式(Factory Pattern)
一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...
- [设计模式3]--工厂(Factory)模式
原文出处:http://blog.csdn.net/lwbeyond/article/details/7528309 工厂模式属于创建型模式,大致可以分为三类,简单工厂模式.工厂方法模式.抽象工厂模式 ...
- Head First 设计模式 —— 04. 工厂 (Factory) 模式
思考题 如何将实例化具体类的代码从应用中抽离,或者封装起来,使它们不会干扰应用的其他部分? P111 将实例化具体类的代码放入一个对象中管理,通过不同入参决定实例化具体的类 简单工厂 不是23种GOF ...
- PHP设计模式(二)工厂方法模式(Factory Method For PHP)
简单工厂简述: 简单工厂模式实现了生产产品类的代码跟客户端代码分离,在工厂类中你可以添加需要生成长跑的逻辑代码(new 产品类),但是问题来了,优秀的代码是符合"开闭原则"如果你要 ...
- JAVA设计模式——第 5 章 工厂方法模式【Factory Method Pattern】(转)
女娲补天的故事大家都听说过吧,今天不说这个,说女娲创造人的故事,可不是“造人”的工作,这个词被现代人滥用了.这个故事是说,女娲在补了天后,下到凡间一看,哇塞,风景太优美了,天空是湛蓝的,水是清澈的,空 ...
- Java设计模式学习笔记(三) 工厂方法模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 简介 上一篇博客介绍了简单工厂模式,简单工厂模式存在一个很严重的问题: 就是当系统需要引入 ...
随机推荐
- 新手学习FFmpeg - 通过API实现可控的Filter调用链
虽然通过声明[x][y]avfilter=a=x:b=y;avfilter=xxx的方式可以创建一个可用的Filter调用链,并且在绝大多数场合下这种方式都是靠谱和实用的. 但如果想精细化的管理AVF ...
- Kubernetes 系列(七):持久化存储StorageClass
前面的课程中我们学习了 PV 和 PVC 的使用方法,但是前面的 PV 都是静态的,什么意思?就是我要使用的一个 PVC 的话就必须手动去创建一个 PV,我们也说过这种方式在很大程度上并不能满足我们的 ...
- spring5 源码深度解析----- 创建AOP代理之获取增强器
在上一篇的博文中我们讲解了通过自定义配置完成了对AnnotationAwareAspectJAutoProxyCreator类型的自动注册,那么这个类到底做了什么工作来完成AOP的操作呢?首先我们看看 ...
- 《完美解决系列》Android5.0以上 Implicit intents with startService are not safe
在Android6.0上,使用了以下代码: Intent intent = new Intent(); intent.setAction("xxx.server"); bindSe ...
- js对数组、对象的深拷贝、复制
基本类型的数据是存放在栈内存中的,而引用类型的数据是存放在堆内存中的 基本类型:Number Boolean undefined String Null 引用类型:Object Function js ...
- 教你如何判断URL的好坏
1.最核心-网站整体内容质量2.关键词整理拓展及关键词布局3.网站外部链接建设4.网站内链建设合理5.面包屑导航6.友情链接7.404页面网站的SEO站外优化+SEO外链建设 层级:三层为好,301重 ...
- 某CTF平台一道PHP代码审计
这道题不是说太难,但是思路一定要灵活,灵活的利用源码中给的东西.先看一下源码. 首先要理解大意. 这段源码的大致的意思就是,先将flag的值读取放在$flag里面. 后面再接受你输入的值进行判断(黑名 ...
- 第二篇 python进阶
目录 第二篇 python进阶 一 数字类型内置方法 二 字符串类型内置方法 三 列表类型内置方法(list) 四 元组类型内置方法(tuple) 五 字典内置方法 六 集合类型内置方法(self) ...
- golang初探与命令源码分析
前段时间有群友在群里问一个go语言的问题: 就是有一个main.go的main函数里调用了另一个demo.go里的hello()函数.其中main.go和hello.go同属于main包.但是在mai ...
- Chrome 和 Chromedriver 的安装和配置
1.Chrome 下载安装地址:https://www.google.com/intl/zh-CN_ALL/chrome/ 2.Chromedriver的安装 方法一: (1) brew cask i ...