类写的不规范,原因: 缩短篇幅,实际中请不要这样写。 欢迎指正

  工厂模式,如其名,想象下现实生活中的工厂,比如Apple的组装工厂,小米产品的组装工厂,华为设备的组装工厂。对我们用户而言,不需要知道他到底是怎么组装的,几道工序,时间长短,这些用户都不需要关心。

1、分类

  A、 简单工厂, 生产一一种产品, 只生产电视,只生产手机

  B、 工厂方法,生产一系列产品, 生产一系列电视、生产一些列手机

  C、 抽象工厂,生产一个品牌产品,生产该品牌下的所有商品,电视,手机都生产。

2、简单工厂

  一句话: 产品来自工厂。这里以 XM 和 TCL 为例

  A、先定义商品类

class mtv
{
public:
// 电视机具有的基本功能
virtual void play() = 0;
};

  B、TCL 电视,继承自电视类

// tcl电视
class tv_tcl : public mtv
{
public:
void play() { cout << "\n\n tcl is running"; }
};

  C、小米电视继承自电视类

// 小米电视
class tv_xm : public mtv
{
public:
void play() { cout << "\n\n xm is running"; }
};

  D、工厂类,生产电视机的。设定一个序号, 1-小米电视, 2-tcl 电视

// 电视机工厂
class mtv_factory
{
public:
mtv *get_tv(const int index )
{
if (2 == index)
return new tv_xm;
else if (1 == index)
return new tv_tcl;
else
throw "it cannot find the tv";
}
};

    齐活儿,电视机和工厂准备好了,下面开始生产电视。调用示例,需要什么电视就向工厂传值:

void call_simple_factory()
{
std::unique_ptr<mtv_factory> ptvfact(new(std::nothrow) mtv_factory);
if (nullptr == ptvfact)
{
cout << "ptvfact = nullptr\n\n"; return;
} std::unique_ptr<mtv> ptv(ptvfact->get_tv(2));
if (nullptr == ptv)
{
cout << "ptv = nullptr\n\n"; return;
} ptv->play();
}

  工厂就一个,负责生产所有的电视。这时,需要增加一种新产品电视小米,就需要添加小米电视机类和工厂添加生产小米的流水线。 新增一种电视产品就需要额外增加代码。

  优点也很明显,各模块之间保持一定的独立, 尽量降低耦合

3、工厂方法

  一句话: 所有的产品都需要来自自己对应工厂。 看下面的例子。这里,以海尔电视为例。需要用到的有: 工厂和产品

  A、电视类, 电视可以播放节目

class tv_brand
{
public:
virtual void play() = 0;
};

  B、海尔电视类, 继承电视类

class tv_brand_haier : public tv_brand
{
public:
void play()
{
cout << "\n\n haier tv is running \n";
}
};

  C、现实中,电视机生产应该是在工厂内完成的,这里,定义一个电视机生产的工厂,专门生产电视

// 总的工厂还是生产电视机
class tv_factory
{
public:
virtual tv_brand *get_tv_brand() = 0;
};

  D、海尔电视机 也需要从 海尔电视机工厂 生产得到,下面定义了海尔电视机工厂,继承自上面C中的电视机工厂

class tv_fact_haier : public tv_factory
{
public:
tv_brand *get_tv_brand()
{
return new tv_brand_haier;
}
};

  齐活儿,电视机工厂有了,电视机工厂也有了电视机产品的设计图,可以开始生产了。

void call_tv_new()
{
std::unique_ptr<tv_factory> phaierfact(new(std::nothrow) tv_fact_haier);
if (!phaierfact)
{
cout << "\n\n 总海尔工厂创建失败 \n\n";
return;
} // 创建工厂对象
std::unique_ptr<tv_brand> ptv_haier(phaierfact->get_tv_brand());
if (!ptv_haier)
{
cout << "\n\n 海尔工厂创建对象失败 \n\n";
return;
} // 播放节目
ptv_haier->play();
}

  调用时,告诉电视机工厂,说,我我需要海尔电视机。 想比 简单工厂, 调用更加简洁了。工厂再也不用判断了,而且代码更加清晰明了。

4、抽象工厂

  还是以海尔为例,现在业务做大了,不仅有电视业务,还有空调业务。于是建立了电视工厂和空调工厂

  A、 电视及类

// 每台电视机都可以播放节目
class tv_brand
{
public:
virtual void play() = 0;
};

  B、海尔电视机类,继承电视类,

class tv_brand_haier : public tv_brand
{
public:
void play()
{
cout << "\n\n haier tv is running \n";
}
};

  C、电视机工厂类

class tv_factory
{
public:
virtual tv_brand *get_tv_brand() = 0;
};

  D、海尔电视机工厂类,继承电视机工厂类,生产电视机

class tv_fact_haier : public tv_factory
{
public:
tv_brand *get_tv_brand()
{
return new tv_brand_haier;
}
};

  E、空调类

// air conditioner
class air_conditioner
{
public:
virtual void change_temperature() = 0;
};

  F、海尔空调类

class air_conditioner_haier : public air_conditioner
{
public:
void change_temperature()
{
cout << "\n\n haier airconditioner is running\n\n";
}
};

  G、空调工厂类

// 空调工厂负责生产对象
class factory_airditioner
{
public:
virtual air_conditioner *get_air_conditioner() = 0;
};

  H、海尔空调工厂类,继承空调工厂类生产海尔空调

class factory_airditioner_haier : public factory_airditioner
{
public:
air_conditioner *get_air_conditioner()
{
return new air_conditioner_haier;
}
};

  I、到此,所有的产品和所有产品对应的工厂准备完毕,海尔需要一个总厂,将其聚拢一起,如下

// haier总工厂
class factory_haier
{
public:
// 空调工厂
factory_airditioner * get_air_conditioner()
{
return new(std::nothrow) factory_airditioner_haier;
} // tv工厂
tv_factory *get_tv()
{
return new(std::nothrow) tv_fact_haier;
}
};

  J、总厂和分工厂也都建好了,分工厂也有了自己的产品样版。下面开始生产商品

void call_haier_facotry()
{
std::unique_ptr<factory_haier> phaier_factory(new(std::nothrow) factory_haier);
if (!phaier_factory)
{
cout << "\n\n 海尔电器总厂创建失败 \n\n";
return;
} // 海尔电视工厂
std::unique_ptr<tv_factory> ptv_haier_fact(phaier_factory->get_tv()); // 海尔空调工厂
std::unique_ptr<factory_airditioner> pair_con_haier_fact(phaier_factory->get_air_conditioner()); if (!ptv_haier_fact)
{
cout << "\n\n\n 海尔电视机工厂创建失败\n\n";
}
else
{
std::unique_ptr<tv_brand> phaier_tv(ptv_haier_fact->get_tv_brand());
if (!phaier_tv)
cout << "\n\n 海尔电视生产失败\n\n";
else
phaier_tv->play();
} if (!pair_con_haier_fact)
{
cout << "\n\n\n 海尔空调工厂创建失败\n\n";
}
else
{
std::unique_ptr<air_conditioner> phaier_air_con(pair_con_haier_fact->get_air_conditioner());
if (!phaier_air_con)
cout << "\n\n 海尔空调生产失败\n\n";
else
phaier_air_con->change_temperature();
}
}

5、总结

  工厂模式需要写相对较多的代码,但是结构清晰,很容易维护。

c++设计模式概述之工厂的更多相关文章

  1. java 28 - 1 设计模式 之 面向对象思想设计原则和模版设计模式概述

    在之前的java 23 中,了解过设计模式的单例模式和工厂模式.在这里,介绍下设计模式 面向对象思想设计原则 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设 ...

  2. OOAD-设计模式(二)之GRASP模式与GOF设计模式概述

    一.GRASP模式(通用责任分配软件模式)概述 1.1.理解责任 1)什么是责任 责任是类间的一种合约或义务,也可以理解成一个业务功能,包括行为.数据.对象的创建等 知道责任——表示知道什么 行为责任 ...

  3. Java设计模式系列-抽象工厂模式

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...

  4. PHP设计模式概述

    PHP设计模式概述 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. ...

  5. java设计模式概述

    java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模 ...

  6. 23种GoF设计模式概述

    23种GoF设计模式概述 在前面,我们对 GoF 的 23 种设计模式进行了分类,这里先对各个设计模式的功能进行简要介绍,以便有个大概了解.后面的章节再进行详细介绍. 创建型模式 关注于怎么创建对象的 ...

  7. Java设计模式(一):设计模式概述、UML图、设计原则

    1 设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中,而是被用于建筑领域的设计中. 1977年美国著名建筑大师.加利福尼亚大学伯克利分校环境结构 ...

  8. 设计模式(一)----设计模式概述及UML图解析

    1.设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中,而是被用于建筑领域的设计中. 1977年美国著名建筑大师.加利福尼亚大学伯克利分校环境结构 ...

  9. C#设计模式之简单工厂模式(Simple Factory)

    1. 概述 简单工厂模式就是将一个类的实例化交给一个静态工厂来执行. 2. 使用频率 中 3. 模式结构 3.1 机构图 3.2 模式中的角色 Product:抽象类,把具体产品类公共的代码进行抽象和 ...

随机推荐

  1. 51nod 1709 复杂度分析

    51nod 1709 复杂度分析 考虑定义 $ F(x) $ 为 \(x\) 为根的子树所有点与 $ x $ 的深度差(其实就是 $ x $ 到每个子树内点的距离)的 1 的个数和. 注意,$ F(x ...

  2. Perl语言编程(大骆驼)

    啰嗦几句 Perl的时代已经过去,现在年轻的同事们基本上都在用Python了.但个人认为单就生物信息文本处理而言,Perl语言是绝对够用的.最主要的是,前辈们搭建的流程大多数是Perl写的,因此,如果 ...

  3. 基因组Denovo组装原理、软件、策略及实施

    目录 1. 组装算法 1)基于OLC算法 2)基于DBG算法 3)OLC vs DBG 2. 组装软件 3. 组装策略 4. 组装项目实施 1)测序前的准备 2) 测序样品准备 3)测序策略的选择 4 ...

  4. LearnPython_week4

    1.装饰器2.生成器3.迭代器4.内置方法5.可序列化6.项目规范化 1.装饰器 # -*- coding:utf-8 -*- # Author:Wong Du ### 原代码 def home(): ...

  5. fastboot烧写Andriod 以及SD 卡烧写LinuxQT,

    EMMC是一种FLASH,SD(TF)卡是另外的一种存储,通过控制拨码开关指引CPU去读EMMC还是SD卡的u-boot文件. u-boot的作用 初始化内存控制区,访问存储器,把内核从存储器读取出来 ...

  6. javaSE高级篇3 — 网络编程 — 更新完毕

    网络编程基础知识 先来思考两个问题( 在这里先不解决 ) 如何准确的找到一台 或 多台主机? 找到之后如何进行通讯? 网络编程中的几个要素 IP 和 端口号 网络通讯协议:TCP / UDP 最后一句 ...

  7. day04 orm操作

    day04 orm操作 昨日内容回顾 小白必会三板斧 request对象方法 静态文件 请求方式 python链接数据库 django链接数据库 小白必会三板斧 HttpResponse :返回前端浏 ...

  8. Linux 易错小结

    修改文件夹(递归修改)权限 chmod -R 777 /html Linux查看进程的4种方法 第一种: ps aux ps命令用于报告当前系统的进程状态.可以搭配kill指令随时中断.删除不必要的程 ...

  9. 对于HTML和XML的理解

    1.什么是HTML??? HTML就是 超文本标记语言(超文本含义:超过文本 --图片 .视频.音频. 超链接) 2.HTML作用 把网页的信息格式化的展现,对网页信息进行规范化展示 连接(https ...

  10. AJAX - Http 中 post 和 get 的区别

    HTTP: post 和 get 是 HTTP 协议中的两种方法.浏览器和服务器的交互是通过 HTTP 协议执行的,他的全称为Hyper Text Transfer Protocol(超文本传输协议) ...