模式定义:

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。

工厂方法让类把实例化推迟到子类。

模式结构:


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

请按随意键继续. . .

设计原则的应用:

设计原则6:依赖倒置原则(Dependency Inversion Priciple):要依赖抽象,不要依赖详细类。

设计原则4:工厂方法用来处理对象的创建,并将这种行为封装在子类中。这样,客户中关于基类的代码和子类对象对象创建代码解耦了。

參考Head First设计模式

设计模式C++实现——工厂方法模式的更多相关文章

  1. 大话设计模式C++版——工厂方法模式

    工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...

  2. IOS设计模式浅析之工厂方法模式(Factory Method)

    概述 在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口. 如何隔离出这个易变对象的变化,使得系统中“其它依赖该对象的对 ...

  3. [设计模式]<<设计模式之禅>>工厂方法模式

    1 女娲造人的故事 东汉<风俗通>记录了一则神话故事:“开天辟地,未有人民,女娲搏黄土做人”,讲述的内容就是大家非常熟悉的女娲造人的故事.开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹 ...

  4. java设计模式-----2、工厂方法模式

    再看工厂方法模式之前先看看简单工厂模式 工厂方法模式(FACTORY METHOD)同样属于一种常用的对象创建型设计模式,又称为多态工厂模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的 ...

  5. C#设计模式之二工厂方法模式(Factory Method Pattern)【创建型】

    一.引言 在上一篇文章中我们讲解了过渡的一种模式叫做[简单工厂],也有叫[静态工厂]的,通过对简单工厂模式得了解,我们也发现了它的缺点,就是随着需求的变化我们要不停地修改工厂里面的方法的代码,需求变化 ...

  6. 大话设计模式Python实现-工厂方法模式

    工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延时到其子类. #!/usr/bin/env python ...

  7. 【C#设计模式3】工厂方法模式

    一.引言 在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,然而本专题介绍的工厂方法模式可以 ...

  8. 重学 Java 设计模式:实战工厂方法模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获!

  9. 《Head First 设计模式》:工厂方法模式

    正文 一.定义 工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个.工厂方法让类把实例化推迟到子类. PS:在设计模式中,"实现一个接口"泛指实现某个超类型(可 ...

随机推荐

  1. 编写testplan

    编写验证计划是验证工作核心技能.衡量标准是完备性.可是写一个完备的验证计划,才开始不是一件容易的事情,需要不断的练习实践. 1.验证计划主要从设计的futurelist中提取.     复杂的futu ...

  2. verilog RTL 编程实践之五

    How to build and test a module 1.test have: generate .stimulus .check .respose 2.only one monitor ca ...

  3. include/autoconfig.mk

    把autoconfig.mk和/include/configs/ $(obj)include/autoconf.mk.dep: $(obj)include/config.h include/commo ...

  4. 杭电 5773 The All-purpose Zero

    Description ?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000). ...

  5. CI框架两个application共用同一套 model

    既然是要共用model文件,就要告诉系统去何处加载我们的模型文件.这个工作是在 Loader.php 这个类中完成的,所以就要修改默认的行为: /** * List of paths to load ...

  6. lnmp环境的使用

    lnmp环境的使用 安装的软件都安装到了:/usr/local 管理nginx service nginx start|stop|restart|reload 管理mysql 直接执行mysql即可登 ...

  7. Unity3D for iOS初级教程:Part 3/3

    转自Unity 3D for iOS 这篇文章还可以在这里找到 英语 Learn how to use Unity to make a simple 3D iOS game! 这份教程是由教程团队成员 ...

  8. [luoguP3668] [USACO17OPEN]Modern Art 2 现代艺术2(栈)

    传送门 还是一个字——栈 然后加一大堆特判 至少我是这么做的 我的代码 #include <cstdio> #include <iostream> #define N 1000 ...

  9. BZOJ3996 [TJOI2015]线性代数 【最小割】

    题目 给出一个NN的矩阵B和一个1N的矩阵C.求出一个1*N的01矩阵A.使得 D=(AB-C)A^T最大.其中A^T为A的转置.输出D 输入格式 第一行输入一个整数N,接下来N行输入B矩阵,第i行第 ...

  10. 算法复习——floyd求最小环(poj1734)

    题目: 题目描述 N 个景区,任意两个景区之间有一条或多条双向的路来连接,现在 Mr.Zeng 想找一条旅游路线,这个路线从A点出发并且最后回到 A 点,假设经过的路线为 V1,V2,....VK,V ...