工厂模式(factory pattern)
工厂模式主要用来封装对象的创建,有3种分类:简单工厂(simple factory)、工厂方法(factory method)、抽象工厂(abstract factory)。
简单工厂包括3种组成元素:抽象产品、具体产品、具体工厂(简单工厂),结构图如下:

C++实现:
//抽象产品
class Car {
public:
virtual string getDescription() = ;
};
//具体产品
class Audi : public Car {
public:
string getDescription() { return "Audi"; }
}; class BMW : public Car {
public:
string getDescription() { return "BMW"; }
}; class Ford : public Car {
public:
string getDescription() { return "Ford"; }
}; class Hummer : public Car {
public:
string getDescription() { return "Hummer"; }
}; class Toyota : public Car {
public:
string getDescription() { return "Toyota"; }
}; class Bentley : public Car {
public:
string getDescription() { return "Bentley"; }
};
//简单工厂
class CarFactory {
public:
Car* createCar(string name) {
if (name == "Audi")
return new Audi;
else if (name == "BMW")
return new BMW;
else if (name == "Ford")
return new Ford;
else if (name == "Hummer")
return new Hummer;
else if (name == "Toyota")
return new Toyota;
else if (name == "Bentley")
return new Bentley;
}
}; int main()
{
CarFactory factory;
Car *mycar = factory.createCar("Audi");
cout << mycar->getDescription() << endl;
mycar = factory.createCar("BMW");
cout << mycar->getDescription() << endl;
delete mycar;
}
可以看出,在简单工厂模式下,一个具体的工厂负责所有具体产品的创建,适用于产品种类较少的情况。当新增产品时,我们需要修改简单工厂的实现逻辑,违背了开放关闭原则。
工厂方法模式在简单工厂模式基础上,增加了一个抽象工厂。

抽象工厂只定义了创建对象的接口,由具体子类负责具体对象的创建。
C++实现:
//抽象工厂
class CarFactory {
public:
virtual Car* createCar() = ;
};
//具体工厂
class AutiCarFactory : public CarFactory {
public:
Car* createCar() { return new Audi; }
}; class BMWCarFactory : public CarFactory {
public:
Car* createCar() { return new BMW; }
}; int main()
{
CarFactory *pcf = new AutiCarFactory;
Car *c = pcf->createCar();
cout << c->getDescription() << endl;
delete pcf; pcf = new BMWCarFactory;
c = pcf->createCar();
cout << c->getDescription() << endl;
delete pcf;
}
在工厂方法模式下,当新增一个产品种类时,只需要创建一个新的产品类和一个新的对应工厂类即可,没有破坏原有代码,遵循了开放关闭原则。
抽象工厂模式比较抽象,为此引入以下两个概念:
产品等级结构:
产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族:
在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
此时再贴张结构图就更清晰了:

抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,
一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品
族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。
抽象工厂的一个应用是:在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。
抽象工厂的一个缺点是:增加新的工厂和产品族容易,增加新的产品等级结构麻烦。
reference:
http://design-patterns.readthedocs.org/zh_CN/latest/creational_patterns/abstract_factory.html
Simple Factory Vs Factory Method Vs Abstract Factory by Example
工厂模式(factory pattern)的更多相关文章
- 设计模式 - 工厂模式(factory pattern) 具体解释
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012515223/article/details/27081511 工厂模式(factory pa ...
- 创建型模式篇(工厂模式Factory Pattern)
一.工厂模式(Factory Pattern) 1.定义: 在软件系统,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.提供一种封 ...
- python 设计模式之工厂模式 Factory Pattern (简单工厂模式,工厂方法模式,抽象工厂模式)
十一回了趟老家,十一前工作一大堆忙成了狗,十一回来后又积累了一大堆又 忙成了狗,今天刚好抽了一点空开始写工厂方法模式 我看了<Head First 设计模式>P109--P133 这25页 ...
- 工厂模式(factory pattern) ------创造型模式
创建型模式 简单工厂模式的缺点是: 当我们引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,需要修改工厂类的方法,违反了“开闭原则”. 工厂模式提供了一个抽象工厂接口来声明抽象工厂方 ...
- 23种设计模式--工厂模式-Factory Pattern
一.工厂模式的介绍 工厂模式让我们相到的就是工厂,那么生活中的工厂是生产产品的,在代码中的工厂是生产实例的,在直白一点就是生产实例的类,代码中我们常用new关键字,那么这个new出来的实例 ...
- 【设计模式】工厂模式 Factory Pattern
1)简单工厂(不是模式) 简单工厂只是一种变成习惯,并非23种设计模式之一. 简单工厂提供将实例话那种类型留给运行时判断,而非编译时指定.简单工厂模式就是由一个工厂类根据传入的参数决定创建出哪一个类的 ...
- JAVA设计模式之工厂模式—Factory Pattern
1.工厂模式简介 工厂模式用于对象的创建,使得客户从具体的产品对象中被解耦. 2.工厂模式分类 这里以制造coffee的例子开始工厂模式设计之旅. 我们知道coffee只是一种泛举,在点购咖啡时需要指 ...
- 设计模式 - 出厂模式(factory pattern) 详细说明
出厂模式(factory pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27081511 工厂方法模式 ...
- 设计模式(一)工厂模式Factory(创建型)
设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.可是在一些情况下, new操作符直接生成对象会带来一些问题. ...
随机推荐
- Struts2-学习笔记系列(15)-ajax支持和JSON
7.1stream类型的result 使用stream就无需jsp页面,直接在action想浏览者生成指定的响应 @Override public java.lang.String execute() ...
- 配置spark历史服务(spark二)
1. 编辑spark-defaults.conf位置文件 添加spark.eventLog.enabled和spark.eventLog.dir的配置修改spark.eventLog.dir为我们之前 ...
- Arthas-Java的线上问题定位工具
Arthas(阿尔萨斯) 能为你做什么? Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱. 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar ...
- c++ string类的一些使用
初始化: string类的初始化是不可以用字符进行的,如; string str='c'; string str('c');必须传递字符串字面量作为参数:string本身是用模板类进行实例化的类. s ...
- windows/linux下如何更换Python的pip源
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:xlixiaohui PS:如有需要Python学习资料的小伙伴可以 ...
- Supermarket POJ - 1456(贪心)
题目大意:n个物品,每个物品有一定的保质期d和一定的利润p,一天只能出售一个物品,问最大利润是多少? 题解:这是一个贪心的题目,有两种做法. 1 首先排序,从大到小排,然后每个物品,按保质期从后往前找 ...
- python_ck01(虚拟环境管理)
拖拖拉拉的毛病还是依旧如初... 断断续续坚持三天总算把虚拟环境管理部分的内容给看完了. 对三天的知识点进行梳理,方便以后回顾. ①虚拟环境安装 用pip install + 包名的方式安装,涉及到的 ...
- linux常用命令--文件和目录
cd /home 进入 '/ home' 目录' cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd 进入个人的主目录 cd ~user1 进入个人的主目录 cd - 返回上次所在的目 ...
- Jmeter系列(2)- Jmeter工具介绍、Jmeter安装目录介绍、Jmeter面板介绍
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html Jmeter支持哪些测试场景? Jme ...
- Redis开发运维的陷阱及避坑指南
原文首发于博客园,作者:后青春期的Keats:地址:https://www.cnblogs.com/keatsCoder/ 转载请注明,谢谢! Linux 配置优化 我们在使用 Redis 过程中,可 ...