C++设计模式之工厂模式(创建型模式)
学习软件设计,向OO高手迈进!
设计模式(Design pattern)是软件开发人员在软件开发过程中面临的一般问题的解决方案。
这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
是前辈大神们留下的软件设计的"招式"或是"套路"。
什么是工厂模式
对于工厂模式,具体上可以分为三类:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
简单工厂模式
简单工厂模式是最简单的设计模式之一,其实它并不属于GOF的23种设计模式,但应用也十分频繁,同时也是其余创建型模式的基础,因此有必要先学习简单工厂模式。
简单工厂基本实现流程
- 设计一个抽象产品类,它包含一些公共方法的声明
- 从抽象产品类中派生出多个具体产品类,具体产品类中实现具体产品生产的相关代码
- 设计一个工厂类,工厂类提供一个生产各种产品的方法,该方法根据传入参数(产品名称)创建不同的具体产品类对象
- 客户端只需调用工厂类的这个方法,并传入具体产品参数,即可得到一个具体产品对象
定义
定义一个简单工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
简单工厂模式结构
从简单工厂模式的定义可以看出,在简单工厂模式中,大体上有3个角色:
- 工厂角色(Creator):这是简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象
- 抽象产品角色(AbstractProduct):这是简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。该类可以是接口,也可以是抽象类
- 具体产品角色(ConcreteProduct):抽象产品的派生类,包含具体产品特有的实现方法,是简单工厂模式的创建目标
UML类图
其UML类图如下
Version 1.0
下面我们使用手机生产来讲解该模式:
一、定义抽象产品类AbstractProduct
Phone类:手机类(AbstractProduct)
class Phone {public:virtual void make(void) = 0;
};
二、定义具体产品类
MiPhone类:小米手机类(Product1)
class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}
};
IPhone类:苹果手机类(Product2)
class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}
};
三、定义工厂类和工厂方法
SimpleFactory类:手机生产工厂类(Factory)
class SimpleFactory {public:static Phone* makePhone(const string& phoneType) {if (phoneType == "MiPhone") {return new MiPhone();} else if (phoneType == "iPhone") {return new IPhone();} return nullptr;}
};
四、客户端
int main(int argc, char** argv) {// make xiaomi phone!Phone* miPhone = SimpleFactory::makePhone("MiPhone"); // make iphonePhone* iPhone = SimpleFactory::makePhone("iPhone"); return 0;
}
执行结果
make xiaomi phone!
make iphone!
Version 1.1
扩展增加生产华为手机实现
一、扩展具体产品类
Huawei类:华为手机类(Product3)
class HuaweiPhone : public Phone {public:HuaweiPhone() {this->make();} virtual void make(void) {cout << "make huawei phone!" << endl;}
};
二、扩展工厂类方法
SimpleFactory类:手机生产工厂类(Factory)
class SimpleFactory {public:static Phone* makePhone(const string& phoneType) {if (phoneType == "MiPhone") {return new MiPhone();} else if (phoneType == "iPhone") {return new IPhone();} else if (phoneType == "HuaweiPhone") {return new HuaweiPhone();}return nullptr;}
};
三、扩展客户端
int main(int argc, char** argv) {// make xiaomi phone!Phone* miPhone = SimpleFactory::makePhone("MiPhone");// make iphonePhone* iPhone = SimpleFactory::makePhone("iPhone");// make huawei phonePhone* huaweiphone = SimpleFactory::makePhone("HuaweiPhone");return 0;
}
执行结果
make xiaomi phone!
make iphone!
make huawei phone!
在简单工厂模式中,工厂类是整个模式的关键所在。它包含了必要的判断逻辑,能够根据外界给定的条件去判断应该创建哪个具体类的实例。用户在使用时可以直接根据工厂类去创建所需的实例,而无需关心这些对象是如何组织并创建的,从这一点上来说,这有利于整个软件体系结构的优化。但是,简单工厂模式的缺点也正体现在工厂类上,由于工厂类中集中了所有实例的创建逻辑,当我们增加了一个新的
具体类时,需要同时修改工厂类(多加一个if),这违反了“开闭原则”。
优点
- 工厂类提供创建具体产品的方法,并包含一定判断逻辑,客户不必参与产品的创建过程。
- 客户只需要知道对应产品的参数即可,参数一般简单好记,如数字、字符或者字符串等。
缺点
- 扩展性差(实例中想增加一种手机产品,除了新增一个手机产品类,还需要修改工厂类方法)。
- 不同的产品需要不同额外参数的时候 不支持。
适用场合
- 在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式。
- 由于对象的创建过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。
工厂方法模式(Factory Method)
定义
定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。
工厂方法模式结构
从工厂方法模式简介中,可以知道该模式有以下几种角色:
- 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法
- 具体工厂(ConcreteFactory):生产具体产品的工厂
- 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
- 具体产品(ConcreteProduct):具体的产品类
UML类图
Version 2.0
接下来继续使用生产手机的例子来讲解该模式:
一、定义抽象产品类AbstractProduct
Phone类:手机类(AbstractProduct)
class Phone {public:virtual void make(void) = 0;
};
二、定义具体产品类
MiPhone类:小米手机类(Product1)
class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}
};
IPhone类:苹果手机类(Product2)
class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}
};
三、定义抽象工厂类AbstractFactory
AbstractFactory类:生产不同产品的工厂的抽象类
class AbstractFactory {public:virtual Phone* makePhone(void) = 0;
};
四、定义具体工厂类
XiaoMiFactory类:生产小米手机的工厂类(ConcreteFactory1)
class XiaoMiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new MiPhone();}
};
AppleFactory类:生产苹果手机的工厂类(ConcreteFactory2)
class AppleFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new IPhone();}
};
五、客户端
int main(int argc, char** argv) {AbstractFactory* miFactory = new XiaoMiFactory();AbstractFactory* appleFactory = new AppleFactory();Phone* miPhone = miFactory->makePhone();Phone* iPhone = appleFactory->makePhone();return 0;
}
执行结果
make xiaomi phone!
make iphone!
Version 2.1
扩展增加生产华为手机实现
一、扩展具体产品类
Huawei类:华为手机类(Product3)
class HuaweiPhone : public Phone{public:HuaweiPhone() {this->make();}virtual void make(void) {cout << "make huawei phone!" << endl;}
};
二、扩展具体工厂类
HuaweiFactory类:生产华为手机的工厂类(ConcreteFactory3)
class HuaweiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new HuaweiPhone();}
};
三、扩展客户端
int main(int argc, char** argv) {AbstractFactory* miFactory = new XiaoMiFactory();AbstractFactory* appleFactory = new AppleFactory();AbstractFactory* huaweiFactory = new HuaweiFactory();Phone* miPhone = miFactory->makePhone();Phone* iPhone = appleFactory->makePhone();Phone* huaweiphone = huaweiFactory->makePhone();return 0;
}
执行结果
make xiaomi phone!
make iphone!
make huawei phone!
优点
- 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂。
- 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键。
- 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。
缺点
- 添加新产品时需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销。
适用场合
- 客户端不需要知道它所需要创建的对象的类。
- 抽象工厂类通过其子类来指定创建哪个对象。
抽象工厂模式(Abstract Factory)
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
简言之,一个工厂可以提供创建多种相关产品的接口,而无需像工厂方法一样,为每一个产品都提供一个具体工厂。
抽象工厂模式结构
抽象工厂模式结构与工厂方法模式结构类似,不同之处在于,一个具体工厂可以生产多种同类相关的产品:
- 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法
- 具体工厂(ConcreteFactory):生产具体产品的工厂
- 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法
- 具体产品(ConcreteProduct):具体的产品类
UML类图
Version 3.0
一、定义A类抽象产品类AbstractProductA
Phone类:定义手机产品的接口(AbstractPhone)
class Phone {public:virtual void make(void) = 0;
};
二、定义具体A类产品类
MiPhone类:小米手机类(Product1)
class MiPhone : public Phone {public:MiPhone() {this->make();}virtual void make(void) {cout << "make xiaomi phone!" << endl;}
};
IPhone类:苹果手机类(Product2)
class IPhone : public Phone {public:IPhone() {this->make();} virtual void make(void) {cout << "make iphone!" << endl;}
};
三、定义B类抽象产品类 AbstractProductB
PC类:定义PC产品的接口(AbstractPC)
class PC {public:virtual void make(void) = 0;
};
四、定义具体B类产品类
小米PC类:定义小米电脑产品(MIPC)
class MiPC : public PC {public:MiPC() {this->make();}virtual void make(void) {cout << "make xiaomi PC!" << endl;}
};
MAC类:定义苹果电脑产品(MAC)
class MAC : public PC {public:MAC() {this->make();}virtual void make(void) {cout << "make MAC!" << endl;}
};
五、定义抽象工厂AbstractFactory
AbstractFactory类
class AbstractFactory {public:virtual Phone* makePhone(void) = 0;virtual PC* makePC(void) = 0;
};
六、定义具体工厂ConcreteProduct
XiaoMiFactory类:小米工厂类(ConcreteFactory1)
class XiaoMiFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new MiPhone();}virtual PC* makePC(void) {return new MiPC();}
};
AppleFactory类:苹果工厂类(ConcreteFactory2)
class AppleFactory : public AbstractFactory {public:virtual Phone* makePhone(void) {return new IPhone();}virtual PC* makePC(void) {return new MAC();}
};
七、客户端
int main(int argc, char** argv) {AbstractFactory* miFactory = new XiaoMiFactory();AbstractFactory* appleFactory = new AppleFactory();Phone* miPhone = miFactory->makePhone();PC* miPC = miFactory->makePC();Phone* iPhone = appleFactory->makePhone();PC* Mac = appleFactory->makePC();return 0;
}
执行结果
make xiaomi phone!
make xiaomi PC!
make iphone!
make MAC!
优点
- 抽象工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂。
- 新加入产品系列时,无需修改原有系统,增强了系统的可扩展性,符合开闭原则。
缺点
- 在已有产品系列中添加新产品时需要修改抽象层代码,对原有系统改动较大,违背开闭原则。
适用场合
- 一系列/家族产品需要被同时使用时,适合使用抽象工厂模式。
- 产品结构稳定,设计完成之后不会向系统中新增或剔除某个产品。
C++设计模式之工厂模式(创建型模式)相关推荐
- 设计模式(二)—— 创建型模式
设计模式(二)-- 创建型模式 文章首发于 掘金 作者:MiyueFE 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 创建型模式,即处理对象创建过程的设计模式,根据实际情况来使 ...
- Prototype原型模式(创建型模式)
1.原型模式解决的问题 现在有一个抽象的游戏设施建造系统,负责构建一个现代风格和古典风格的房屋和道路. 前提:抽象变化较慢,实现变化较快(不稳定) 整个抽象的游戏设施建造系统相对变化较慢,本例中只有一 ...
- java设计模式中不属于创建型模式_23种设计模式第二篇:java工厂模式定义:工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式...
23种设计模式第二篇:java工厂模式 定义: 工厂模式是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 工厂模式主要是为创建对象提供过渡接口, ...
- 《设计模式详解》创建型模式 - 工厂模式
<设计模式详解> 4.2 工厂模式 4.2.1 概述 4.2.2 简单工厂模式 4.2.2.1 结构 4.2.2.2 实现 4.2.2.3 优缺点 4.2.2.4 扩展 - 静态工厂 4. ...
- 【Java设计模式 设计模式与范式】创建型模式 四:抽象工厂模式
本篇Blog继续学习创建型模式,创建型模式的主要关注点是怎样创建对象,它的主要特点是将对象的创建与使用分离,这样可以降低系统的耦合度,使用者不需要关注对象的创建细节.本篇学习的是抽象工厂模式.由于学习 ...
- 设计模式(三)创建型模式
前言 根据菜鸟教程的目录,我们首先来看看创建型模式. 创建型模式研究: 实际应用中通常有哪些不同的创建对象的场景: 在不同的场景下,如何更好地编写创建对象的代码. 主要研究构造函数. 下面分别对创建型 ...
- 《设计模式详解》创建型模式 - 建造者模式
建造者模式 4.4 建造者模式 4.4.1 概述 4.4.2 结构 4.4.3 实例 4.4.4 优缺点 4.4.5 使用场景 4.4.6 扩展 - 构建对象 重构前 重构后 4.5 创建型模式对比 ...
- 《设计模式详解》创建型模式 - 原型模式
原型模式 4.3 原型模式 4.3.1 概述 4.3.2 结构 4.3.3 实现 4.3.4 案例 4.3.5 使用场景 4.3.6 扩展 - 深克隆 引用对象的浅克隆 实现 1:文件流 + 对象流 ...
- 《设计模式》读书笔记——创建型模式
设计模式 创建模式 定义: 创建型模式抽象了实例化过程.他们帮助一个系统独立于如何创建.组合和表示它的那些对象 一个类创建型模式使用继承改变被实例化的类,而一个对象创建模式是将实例化委托给另一个对象 ...
最新文章
- 我的WCF之旅(6):在Winform Application中调用Duplex Service出现TimeoutException的原因和解决方案...
- python null byte_如何以“正确”的方式处理带有nullbytes的Python unicode字符串?
- [unreal4入门系列之五] 熟悉关卡编辑器界面
- 1.3 torch_向量/矩阵操作
- 打开MSN提示Windows Live Communication Platform遇到问题需要关闭错误的解决方法
- linux循环脚本while循环,Shell脚本while、until循环语句简明教程
- linux系统官方版下载 百度云,百度网盘linux版
- 大数据爬虫的一些小目标
- 微信商城制作的步骤是什么?微信商城模板大全
- 放大镜原理分析及jquery实现
- backdrop-filter: blur() safari 浏览器 无效 解决
- 边缘检测论文简读、开源代码和数据集合集
- 一键生成?从照片生成人脸 3D 模型 #AvatarMe
- LeetCode881:救生艇 (C、C++实现)
- 个性化习题推荐-Exercise recommendation based on knowledge concept prediction
- wps office word 插入图片显示异常 只显示一个长条
- Dubbo服务端服务发布(一)Invoker创建
- 字节数组byte[]转有符号short和无符号unsignedShort
- 阿德莱德大学计算机专业本科几年,阿德莱德大学工程本科学制
- 计算机大专生的平均工资水平,大学/大专应届毕业生工资待遇分析报告 - 职业圈...