设计模式C++实现——工厂方法模式
模式定义:
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。
工厂方法让类把实例化推迟到子类。
模式结构:
Creator是一个类,它实现了全部操纵产品的方法,但不实现工厂方法。
Creator的全部子类都必须实现工厂方法(factoryMethod()),以实际制造出产品。
全部的产品必须实现Product基类。这样一来使用这些产品的类就能够引用这个基类,而不是派生类。
举例:
披萨店希望可以开一些加盟店。
经营者希望确保加盟店运营的质量,所以希望这些店都使用能经过实践考研的代码。问题在于每家加盟店都可能想要提供不同风味的披萨(例如说纽约。芝加哥,加州)。这收到了开店地点及该地区披萨口味的影响。
解决的方法:让每一个区域风味的披萨工厂继承基类披萨工厂使披萨工厂的订单系统不变。然后创建自己风味的披萨。这样真正选购披萨类型,使用详细的披萨工厂决定的。
类图设计:
编程实现及运行结果:
#include <iostream>
#include <string>
#include <list>
using namespace std;
首先创建Pizza类
class Pizza
{
public:
Pizza(string nam, string doug, string sauc)
{
name = nam;
dough = doug;
sauce = sauc;
}
void addTops(string tops)
{
toppings.push_back(tops);
} void prepare()
{
cout << "Preparing " << name << endl;
cout << "Tossing dough" << endl;
cout << "Adding sauce" << endl;
cout << "Adding toppings" << endl;
list<string>::iterator iter = toppings.begin();
for(; iter!=toppings.end(); ++iter)
{
cout << " "<< *iter;
}
cout << endl;
} void bake()
{
cout << "Bake for 25 minutes at 350" << endl;
} void cut()
{
cout << "Cutting the pizza into diagonal slices" << endl;
} void box()
{
cout << "Place pizza in offical PizzaStore box" << endl;
} string getName()
{
return name;
} private:
string name;
string dough;
string sauce;
list<string> toppings;
};
然后创建纽约cheese风格的pizza类和纽约clam风格的pizza类
class NYStyleCheesePizza : public Pizza
{
public:
NYStyleCheesePizza():Pizza("NY Style Sauce and Cheese Pizza",
"Thin Crust Dough", "Marinara Sauce")
{
addTops("Grated Reggiano Cheese");
}
};
class NYStyleClamPizza : public Pizza
{
public:
NYStyleClamPizza():Pizza("NY Style Sauce and Clam Pizza",
"Thin Crust Dough", "Marinara Sauce")
{
addTops("Grated Clam");
}
};
创建基类工厂
class PizzaStore
{
public:
virtual ~PizzaStore(){} Pizza* oderPizza(string type)
{
Pizza* pizza = createPizza(type);
pizza->prepare();
pizza->bake();
pizza->cut();
pizza->box(); return pizza;
} virtual Pizza* createPizza(string type){return NULL;} };
创建详细类工厂(纽约pizza工厂)
class NYPizzaStore : public PizzaStore
{
public:
Pizza* createPizza(string item)
{
if(item == "cheese")
{
return new NYStyleCheesePizza();
}
else if(item == "clam")
{
return new NYStyleClamPizza();
}
else
return NULL;
}
};
//...创建其它地区工厂...
客户代码:
int main()
{
PizzaStore* nyStore = new NYPizzaStore();
Pizza* pizza = nyStore->oderPizza("cheese");
cout << "Ethan ordered a "<< pizza->getName() << endl; return 0;
}
运行结果:
PreparingNY Style Sauce and Cheese Pizza
Tossingdough
Addingsauce
Addingtoppings
Grated Reggiano Cheese
Bakefor 25 minutes at 350
Cuttingthe pizza into diagonal slices
Placepizza in offical PizzaStore box
Ethanordered a NY Style Sauce and Cheese Pizza
请按随意键继续. . .
设计原则的应用:
设计原则4:工厂方法用来处理对象的创建,并将这种行为封装在子类中。这样,客户中关于基类的代码和子类对象对象创建代码解耦了。
參考Head First设计模式
设计模式C++实现——工厂方法模式的更多相关文章
- 大话设计模式C++版——工厂方法模式
工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...
- IOS设计模式浅析之工厂方法模式(Factory Method)
概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...
- [设计模式]<<设计模式之禅>>工厂方法模式
1 女娲造人的故事 东汉<风俗通>记录了一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,讲述的内容就是大家非常熟悉的女娲造人的故事.开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹 ...
- java设计模式-----2、工厂方法模式
再看工厂方法模式之前先看看简单工厂模式 工厂方法模式(FACTORY METHOD)同样属于一种常用的对象创建型设计模式,又称为多态工厂模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的 ...
- C#设计模式之二工厂方法模式(Factory Method Pattern)【创建型】
一.引言 在上一篇文章中我们讲解了过渡的一种模式叫做[简单工厂],也有叫[静态工厂]的,通过对简单工厂模式得了解,我们也发现了它的缺点,就是随着需求的变化我们要不停地修改工厂里面的方法的代码,需求变化 ...
- 大话设计模式Python实现-工厂方法模式
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延时到其子类. #!/usr/bin/env python ...
- 【C#设计模式3】工厂方法模式
一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...
- 重学 Java 设计模式:实战工厂方法模式
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!
- 《Head First 设计模式》:工厂方法模式
正文 一.定义 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类. PS:在设计模式中,"实现一个接口"泛指实现某个超类型(可 ...
随机推荐
- Python基础:列表(list)和元组(tuple)
学一门语言,可以用对比其他语言方法加深对这门语言特点的理解. 一.定义:列表和元组,都是一个可以放置任意数据类型的有序集合. mutable的列表:动态的,可以改变元素 immutable的元组:静态 ...
- python--MySQL权限管理 数据备份还原
一 权限管理 mysql最高管理者是root用户, 这个一般掌握在公司DBA手里, 当你想去对数据库进行一些操作的时候,需要DBA授权给你. 1. 对新用户增删改 1. 创建用户 # 要先use my ...
- python 学习第二周总复习
目录 数据类型内置方法 数字类型内置方法 整型 浮点型 字符串类型内置方法 列表类型内置方法 元祖类型内置方法 字典类型内置方法 集合类型内置方法 布尔类型 数据类型总结 拷贝 浅拷贝 深拷贝 053 ...
- 关于requirejs和grunt压缩合并是否矛盾
requirejs主要是为了模块化开发,这样带来的好处不言而喻.但是分成多个js文件增加了请求数,那么就要用到合并压缩.合并压缩了原来的许多独立的js模块,那requirejs又是怎么冲压缩的文件中找 ...
- 面试准备——redis
https://blog.csdn.net/yangzhong0808/article/details/81196472 http://www.imooc.com/article/36399 http ...
- ActionProxy相关实现类
package com.opensymphony.xwork2; import com.opensymphony.xwork2.config.Configuration; import com.ope ...
- 【UML】关联、依赖、泛化、实现等关系说明
导读:再上一篇博客中,介绍了UML的9种图,现在,将对UML中的关系进行总结.图很重要,但图形中的各种关系也很重要,这扯关系的事儿,从来都是大事儿. 一.基本定义 1.1 总体说明 1.2 具体定义 ...
- POJ-1442 Black Box,treap名次树!
Black Box 唉,一天几乎就只做了这道题,成就感颇低啊! 题意:有一系列插入查找操作,插入每次 ...
- 九度oj 题目1450:产生冠军
题目描述: 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛. 球赛的规则如下: 如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打败C. 如果A打败了B ...
- Title共通写法
用: <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_c ...