【C++设计模式二】工厂模式
(1)定义3
简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。
定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。
(2)结构
工厂模式结构如下:
- 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
- 具体工厂(ConcreteFactory):生产具体的产品;
- 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法;
- 具体产品(ConcreteProduct):具体的产品类。
(3)实例
Factory.h
#ifndef FACTORY_H
#define FACTORY_H
#include <iostream>
#include <string>
/********************************产品类***********************************/
//抽象产品类AbstractProduct(并非真正意义上的抽象类,含有纯虚函数才是抽象类)
class AbstractSportProduct
{
public:
AbstractSportProduct(){}
~AbstractSportProduct(){}
//虚函数
virtual void play(){}
};
//具体产品类Basketball
class Basketball :public AbstractSportProduct
{
public:
Basketball(){}
~Basketball(){}
//具体实现方法
void play();
};
//具体产品类Football
class Football :public AbstractSportProduct
{
public:
Football(){}
~Football(){}
//具体实现方法
void play();
};
/********************************工厂类***********************************/
//抽象工厂类
class AbstractFactory{
public:
//纯虚函数
virtual AbstractSportProduct *getSportProduct() = 0;
};
//具体工厂类BasketballFactory
class BasketballFactory:public AbstractFactory
{
public:
BasketballFactory(){}
~BasketballFactory(){}
AbstractSportProduct *getSportProduct();
};
//具体工厂类FootballFactory
class FootballFactory:public AbstractFactory
{
public:
FootballFactory(){}
~FootballFactory(){}
AbstractSportProduct *getSportProduct();
};
#endif // FACTORY_H
Factory.cpp
#include "Factory.h"
/********************************产品类方法***********************************/
//Basketball方法
void Basketball::play(){
printf("play Basketball\n");
}
//Football方法
void Football::play(){
printf("play Football\n");
}
/********************************工厂类方法***********************************/
//BasketballFactory方法
AbstractSportProduct *BasketballFactory::getSportProduct()
{
return new Basketball();
}
//FootballFactory方法
AbstractSportProduct *FootballFactory::getSportProduct()
{
return new Football();
}
main.cpp
#include "Factory.h"
int _tmain(int argc, _TCHAR* argv[])
{
AbstractSportProduct *pro = nullptr;
AbstractFactory *fac = nullptr;
fac = new BasketballFactory();
pro = fac->getSportProduct();
pro->play();
fac = new FootballFactory();
pro = fac->getSportProduct();
pro->play();
return 0;
}
输出结果:

(4)总结
如果想增加棒球(Baseball)类,只需要增加一个棒球工厂(BaseballFacory),然后在客户端代码中修改具体工厂类的类名,而原有的类的代码无需修改。由此可看到,相较简单工厂模式,工厂方法模式更加符合开闭原则。工厂方法是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。
优点:
- 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
- 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键;
- 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。
缺点:
- 添加新产品时,需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销;
- 工厂和产品都引入了抽象层,客户端代码中均使用的抽象层,增加了系统的抽象层次和理解难度。
【C++设计模式二】工厂模式的更多相关文章
- Java 设计模式之工厂模式(二)
原文地址:Java 设计模式之工厂模式(二) 博客地址:http://www.extlight.com 一.背景 本篇内容是 Java 设计模式创建型模式的第二篇.上一篇主题为 <Java 设计 ...
- 浅析JAVA设计模式之工厂模式(二)
1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...
- 5. 星际争霸之php设计模式--抽象工厂模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 3. 星际争霸之php设计模式--简单工厂模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
- Spring 实现两种设计模式:工厂模式和单态模式(单例模式)
本文摘自:李刚 著 <轻量级 Java EE企业应用实战 Struts2+Spring+hibernate整合开发> 在Spring 中大量使用的以下两种设计模式:工厂模式和单态模式. 工 ...
- python设计模式之工厂模式
一.理解工厂模式 在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类.通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法.客户端使用某些参数调用此方法,之后,工厂会据此创建所需类 ...
- js设计模式:工厂模式、构造函数模式、原型模式、混合模式
一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.a ...
- C# 设计模式之工厂模式(一)
写在前面,PS一句:笔记专用,轻拍勿喷,看的不爽绕路前行即可. 一.举栗说明 1.剧情:某银行财务有三位员工,分别为A.B.C三人,主要任务就是去银行取钱,如下: class EmloyeeA: { ...
- 设计模式——抽象工厂模式及java实现
设计模式--抽象工厂模式及java实现 设计模式在大型软件工程中很重要,软件工程中采用了优秀的设计模式有利于代码维护,方便日后更改和添加功能. 设计模式有很多,而且也随着时间在不断增多,其中最著名的是 ...
随机推荐
- pytest封神之路第二步 132个命令行参数用法
在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...
- Flash 0day(CVE-2018-4878)复现过程
一.前言介绍 2018年2月1号,Adobe官方发布安全通报(APSA18-01),声明Adobe Flash 28.0.0.137及其之前的版本,存在高危漏洞(CVE-2018-4878). 从Ad ...
- Beauty Contest(POJ 2187)
原题如下: Beauty Contest Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 42961 Accepted: ...
- python之requests.session()使用
背景:使用requests.session会话对象先登录至豆瓣网,再进入“我的豆瓣”. 首先说一下,为什么要进行会话保持的操作? requests库的session会话对象可以跨请求保持某些参数. 说 ...
- charles 入门配置(win10+vivoX20)(Charles一)
charles的几个功能可以参考:https://www.cnblogs.com/mihoutao/p/10601171.html 首先是charles的下载 下载地址:https://www.cha ...
- 被喷了!聊聊我开源的RPC框架那些事
前段时间利用业余时间写了一个简单的 RPC 框架,花费了不少精力.开源出来之后,少部分不太友好的技术人站在上帝视角说了风凉话.就很难受,兄弟,谁还没有一个玻璃心. 简单吐槽一波,给大家聊聊关于 gui ...
- Linux实战(16):Centos history命令进阶
因在使用history命令是发现历史命令不同步,没有时间戳,在查看历史操作的时候很不方便,特查询了相关文档,发现可通过系统自带的logger来记录跟踪,历史命令执行的用户,时间,登录IP. vim / ...
- git代码管理——克隆项目到本地仓库及上传本地项目到仓库
一.克隆项目到本地仓库 1.github网站操作 1.1 登录github 首先创建一个仓库,点击“New” 1.2 输入仓库信息 1.3 创建完成后,会多出一个仓库 2.安装git客户端 2.1 安 ...
- Istio 运维实战系列(2):让人头大的『无头服务』-上
本系列文章将介绍用户从 Spring Cloud,Dubbo 等传统微服务框架迁移到 Istio 服务网格时的一些经验,以及在使用 Istio 过程中可能遇到的一些常见问题的解决方法. 什么是『无头服 ...
- 容器云平台No.3~kubernetes使用
今天是是第三篇,接着上一篇继续 首先,通过kubectl可以看到,三个节点都正常运行 [root@k8s-master001 ~]# kubectl get no NAME STATUS ROLES ...