前言

模式介绍

简单工厂模式其实并不属于GoF23(23种设计模式),更类似工厂模式的一种变型。其定义是可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

这就有点像去饭馆吃饭,进了门和服务员说一句:“waiter!来一份海参炒面!” 一般情况下他只会给你海参炒面(不管里面有没有海参)。这会第二个人进来了,也喊了一句:“服务员,来一碗辣根汤面!”此时他就会给你一份辣根汤面。你们根本不会考虑海参炒面和辣根汤面咋炒的,只需要告诉店家,他就给你了。

上面实例中的“服务员”就是一个简单工厂。饭馆里的菜单就是简单工厂中的类列表。可以通过告知服务员点哪个类,服务员将类的实例也就是菜品端出来。这样对于我这个这个客户端来讲,没必要知道后厨做了什么,只需要拿到实例菜品吃就好了。如果终于有一天海参炒面变成了烧烤店,但是我也没必要知道后厨咋串的串儿,只需要进去还找服务员,要腰子就OK了。

UML类图

这里涉及到2种类,①我:客户端,负责调用服务员生成后端菜品实例。②服务员:工厂类,负责产生后端菜品并返回给客户端。③菜品:后端菜品类,生成的菜品。具体关系如下UML类图:

代码实例

下面是noodle类,是一个抽象类,里面具备一个eating函数,是为客户端准备的,食用。

#ifndef NOODLE_H
#define NOODLE_H class noodle {
public:
noodle() {}
~noodle() {} public:
virtual void eating() = 0;
}; #endif // NOODLE_H

下面是海参炒面类,集成自noodle类,实现了eating方法:

#ifndef HAISHENNOODLE_H
#define HAISHENNOODLE_H #include "noodle.h" class haishennoodle : public noodle
{
public:
haishennoodle();
~haishennoodle(); public:
virtual void eating();
}; #endif // HAISHENNOODLE_H
#include <iostream>
#include "haishennoodle.h" haishennoodle::haishennoodle()
{ } haishennoodle::~haishennoodle()
{ } void haishennoodle::eating()
{
std::cout << "我是海参炒面,里面没有海参哦!!吃的时候注意!" << std::endl;
}

下面是辣根汤面类,继承了noodle类,重写了eating方法:

#ifndef LAGENNOODLE_H
#define LAGENNOODLE_H #include "noodle.h" class lagennoodle : public noodle
{
public:
lagennoodle();
~lagennoodle(); public:
virtual void eating();
}; #endif // LAGENNOODLE_H
#include <iostream>
#include "lagennoodle.h" lagennoodle::lagennoodle()
{ } lagennoodle::~lagennoodle()
{ } void lagennoodle::eating()
{
std::cout << "我是辣根汤面,吃完呛的哼啊!!!" << std::endl;
}

下面是服务员类,负责生成后端noodle。通过createnoodle生成noodle实例化,是工厂。

#ifndef WAITER_H
#define WAITER_H class noodle;
class waiter
{
public:
waiter();
~waiter(); public:
noodle *createnoodle(int type);
}; #endif // WAITER_H
#include <iostream>
#include "waiter.h"
#include "haishennoodle.h"
#include "lagennoodle.h" waiter::waiter()
{ } waiter::~waiter()
{ } noodle *waiter::createnoodle(int type)
{
noodle *n = NULL;
switch(type) {
case 0:
n = new haishennoodle();
break;
case 1:
n = new lagennoodle();
break;
default:
std::cout << "对不起,我们这没有这个菜,请您换一个!" << std::endl;
} return n;
}

客户端代码如下,是我进店来点餐的步骤:

#include <iostream>
#include <string.h>
#include "haishennoodle.h"
#include "lagennoodle.h"
#include "waiter.h" using namespace std; char *product_list[] = {
"haishen-noodle",
"lagen-noodle",
NULL
}; int main()
{
char *p = NULL;
char *pd = "haishen-noodle";
int i = 0; waiter *w = new waiter();
noodle *n = NULL; for(p = product_list[i]; p != NULL; i++, p = product_list[i]) {
if(strncmp(pd, p, strlen(pd)) == 0) {
n = w->createnoodle(i);
if(n) {
cout << "开吃!!!" << endl;
n->eating();
}
}
} if(n) {
delete n; n = NULL;
} if(w) {
delete w; w = NULL;
} return 0;
}

附赠CMakeList.txt代码:

cmake_minimum_required(VERSION 2.8)

project(noodle)
set(SRC_LIST main.cpp noodle.h lagennoodle.h lagennoodle.cpp haishennoodle.h haishennoodle.cpp waiter.h waiter.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})

编译运行结果

代码下载链接是:https://github.com/erguangqiang/freesir_headfirst/blob/master/noodle.tar.gz

使用cmake生成Makefile,并编译出可执行程序noodle。运行结果如下:

erguangqiang@elab$./noodle
开吃!!!
我是海参炒面,里面没有海参哦!!吃的时候注意!

结束

使用简单工厂模式优点就是可以隔离客户端和实例化,这样客户端可以不理会类实例化的具体流程,达到了给客户端和逻辑解耦的目的。

但是简单工厂模式缺点也很严重,根据设计模式的开放-封闭原则,对于程序的扩展,不应改变类具体代码,可以对类集成扩展开放。一旦面馆出了新菜品,就需要修改工厂类。规避的方法是使用工厂模式,通过扩展的方式来实现。

深入浅出《设计模式》之简单工厂模式(C++)的更多相关文章

  1. C#设计模式(2)-简单工厂模式

    引言 上一遍中介绍了设计模式中的单例模式-C#设计模式(1)-单例模式,本篇将介绍简单工厂模式,也是比较容易理解的一种模式: 简单工厂模式简介 什么是简单工厂模式? 定义一个工厂类,它可以根据参数的不 ...

  2. C#设计模式(2)——简单工厂模式(转)

    C#设计模式(2)——简单工厂模式   一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理 ...

  3. Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  4. 设计模式之简单工厂模式(Simple Factory)

    原文地址:http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2579100.html 今天呢,要学习的设计模式是“简单工厂模式”,这是一个 ...

  5. iOS设计模式 - (3)简单工厂模式

    iOS设计模式 - (3)简单工厂模式           by Colin丶 转载请注明出处:              http://blog.csdn.net/hitwhylz/article/ ...

  6. 设计模式之简单工厂模式Simple Factory(四创建型)

    工厂模式简介. 工厂模式专门负责将大量有共同接口的类实例化 工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类. 工厂模式有三种形态: 1.简单工厂模式Simple Factory ...

  7. php实现设计模式之 简单工厂模式

    作为对象的创建模式,用工厂方法代替new操作. 简单工厂模式是属于创建型模式,又叫做静态工厂方法模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. 工厂 ...

  8. [python实现设计模式]-3.简单工厂模式-触宝开放平台

    预备知识: 开放封闭原则(Open-Closed Principle OCP) Software entities(classes,modules,functions etc) should open ...

  9. C++实现设计模式之 — 简单工厂模式

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4251756.html 所谓简单工厂模式,是一种实例化对象的方式,只要输入需要实例化对象的名字 ...

  10. C#设计模式之简单工厂模式

    简单工厂模式解释:  简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern) 是通过专门定义一 ...

随机推荐

  1. VUE组内培训

    最近去参加了一个外部VUE的周末培训,加上自己比较感兴趣所以对这项很热的前端框架做了点学习,顺便给组内同事做个简单的分享,希望下次有项目可以使用上- VUE的语法教程网上很多我就不一一列举,截图放一下 ...

  2. 计算机基础 python入门

    1.计算机基础 计算机组成: 输入输出设备内. 存储器 .cpu .电源 .显卡 中央处理器(cpu) 处理各种数据 相当于人的大脑 内存 存储数据 相当于临时记忆 硬盘 存储数据 相当于人的永久记忆 ...

  3. java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x8E' for column 'name' at row 1

    我的错误案例: ,这个后台插不进去,就姓名那栏的中文编码问题. 遇到这个错误,应该是创建表的时候没有设置好编码,这个错误不用多想,我也试过在更改表那里设置编码,但还是不行,还是有残留 直接drop t ...

  4. 2019 Multi-University Training Contest 1 E Path(最短路+最小割)

    题意 链接:https://vjudge.net/problem/HDU-6582 给定一个有向图,可以有重边,每条边上有一个权值表示删掉这条边的代价,问最少花费多少代价能使从s到t节点的最短路径增大 ...

  5. ISODATA聚类算法的matlab程序

    ISODATA聚类算法的matlab程序 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 参考:Kmeans及ISODATA算法的matlab实现 算法 ...

  6. 【洛谷P4251】[SCOI2015]小凸玩矩阵(二分+二分图匹配)

    洛谷 题意: 给出一个\(n*m\)的矩阵\(A\).现要从中选出\(n\)个数,任意两个数不能在同一行或者同一列. 现在问选出的\(n\)个数中第\(k\)大的数的最小值是多少. 思路: 显然二分一 ...

  7. 初学JavaScript正则表达式(八)

    JavaScript正则贪婪模式与非贪婪模式 贪婪模式: 例: \d{3,6} 匹配数字3到6次(正则表达式默认为贪婪模式,即匹配最多次,失败即停) '12345678'.replace(/\d{3, ...

  8. 2. Linux文件与目录管理

    一.目录与路径 1. 相对路径与绝对路径 绝对路径:路径写法[一定由根目录 / 写起],如:/usr/share/doc 相对路径:路径写法[不由 / 写起], /usr/share/doc 要到 / ...

  9. 爬虫scrapy模块

    首先下载scrapy模块 这里有惊喜 https://www.cnblogs.com/bobo-zhang/p/10068997.html 创建一个scrapy文件 首先在终端找到一个文件夹 输入 s ...

  10. Tensorflow之多元线性回归问题(以波士顿房价预测为例)

    一.根据波士顿房价信息进行预测,多元线性回归+特征数据归一化 #读取数据 %matplotlib notebook import tensorflow as tf import matplotlib. ...