(转)设计模式(五)简单工厂模式+工厂方法模式

  

  在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。

模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实例的细节和复杂过程呢?

解决方案:建立一个工厂来创建对象

实现:

一、引言

1)还没有工厂时代:假如还没有工业革命,如果一个客户要一款宝马车,一般的做法是客户去创建一款宝马车,然后拿来用。

2)简单工厂模式:后来出现工业革命。用户不用去创建宝马车。因为客户有一个工厂来帮他创建宝马.想要什么车,这个工厂就可以建。比如想要320i系列车。工厂就创建这个系列的车。即工厂可以创建产品。

3)工厂方法模式时代:为了满足客户,宝马车系列越来越多,如320i,523i,30li等系列一个工厂无法创建所有的宝马系列。于是由单独分出来多个具体的工厂。每个具体工厂创建一种系列。即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象。你需要指定某个具体的工厂才能生产车出来。

4)抽象工厂模式时代:随着客户的要求越来越高,宝马车必须配置空调。于是这个工厂开始生产宝马车和需要的空调。

  最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车.

  这就是工厂模式。

二、分类

  工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。   

工厂模式可以分为三类:

  1)简单工厂模式(Simple Factory) 
  2)工厂方法模式(Factory Method) 
  3)抽象工厂模式(Abstract Factory)

  这三种模式从上到下逐步抽象,并且更具一般性。 
  GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

三、还没有工厂时代

  从无到有。客户自己创建宝马车,然后拿来用。

  

 1 /*
 2 @author CodingMengmeng
 3 @datetime:2016-9-29 17:27:51
 4 @description:a client create a BMW car by himself.
 5 */
 6 #include <iostream>
 7 #include "tchar.h"
 8 using namespace std;
 9
10 class CBMW320{
11 public:
12     CBMW320()
13     {
14         cout << "Produce --> BMW320"<< endl;
15     }
16     ~CBMW320(){};
17
18 };
19
20 class CBMW523{
21 public:
22     CBMW523()
23     {
24         cout << "Produce --> BMW523" << endl;
25     }
26     ~CBMW523(){};
27 };
28
29 int _tmain(int agrc, _TCHAR** argv)
30 {
31     CBMW523* bmw523 = new CBMW523();
32     CBMW320* bmw320 = new CBMW320();
33     return 0;
34 }

运行结果:

  

说明:客户需要知道怎么去创建一款车,客户和车就紧密耦合在一起了.为了降低耦合,就出现了工厂类,把创建宝马的操作细节都放到了工厂里面去,客户直接使用工厂的创建工厂方法,传入想要的宝马车型号就行了,而不必去知道创建的细节。这就是工业革命:简单工厂模式

四、简单工厂模式

  即我们建立一个工厂类方法来制造新的对象。如图:

  

 1 /*
 2 @author CodingMengmeng
 3 @datetime:2016-9-29 17:57:34
 4 @description:Simple Factory Pattern.
 5 */
 6 #include <iostream>
 7 #include "tchar.h"
 8 using namespace std;
 9
10 //抽象产品角色
11 class CBMW{
12 public:
13     CBMW(){}
14     ~CBMW(){}
15 };
16
17 //具体产品角色
18 class CBMW320 :public CBMW{
19 public:
20     CBMW320()
21     {
22         cout << "Produce -->BMW320" << endl;
23     }
24     ~CBMW320(){};
25 };
26
27 class CBMW523 :public CBMW{
28 public:
29     CBMW523()
30     {
31         cout << "Produce -->BMW523" << endl;
32     }
33     ~CBMW523(){};
34
35 };
36
37 //工厂类角色
38 class CFactory{
39 public:
40     CFactory(){};
41     ~CFactory(){};
42     CBMW* createBMW(int type)
43     {
44         switch (type){
45         case 320:    return new CBMW320();
46         case 523:    return new CBMW523();
47
48         default:
49             break;
50         }
51         return NULL;
52     }
53 };
54
55 //客户操作
56 int _tmain(int argc, _TCHAR** argv)
57 {
58     CFactory* factory = new CFactory();
59     CBMW* bmw320 = factory->createBMW(320);
60     CBMW* bmw523 = factory->createBMW(523);
61
62     return 0;
63 }

运行结果:

  

  简单工厂模式又称为静态工厂方法模式。重命名上就可以看出这个模式一定很简单。它存在的目的很简单:定义一个用于创建对象的接口。

  先来看看它的组成

   1) 工厂类角色:这是本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品
       2) 抽象产品角色:它一般是具体产品继承的父类或者实现的接口。         
       3) 具体产品角色:工厂类所创建的对象就是此角色的实例。在C++中由一个继承自抽象产品类的子类来实现。  

  下面我们从开闭原则(对扩展开放;对修改封闭)上来分析下简单工厂模式。当客户不再满足现有的车型号的时候,想要一种速度快的新型车,只要这种车符合抽象产品制定的合同,那么只要通知工厂类知道就可以被客户使用了。所以对产品部分来说,它是符合开闭原则的;但是工厂部分好像不太理想,因为每增加一种新型车,都要在工厂类中增加相应的创建业务逻辑(createBMW(int type)方法需要新增case),这显然是违背开闭原则的。可想而知对于新产品的加入,工厂类是很被动的。对于这样的工厂类,我们称它为全能类或者上帝类。

  我们举的例子是最简单的情况,而在实际应用中,很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品,所以这可能会把我们的上帝累坏了,也累坏了我们这些程序员。
  于是工厂方法模式作为救世主出现了。 工厂类定义成了接口,而每新增的车种类型,就增加该车种类型对应工厂类的实现,这样工厂的设计就可以扩展了,而不必去修改原来的代码。

五、工厂方法模式

  工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

  工厂模式使用的频率非常高,其定义为:

   Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses。定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

  工厂方法模式的通用类图如下图所示。

   

工厂方法模式组成

1)抽象工厂角色:这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在C++中它由抽象类来实现。

2)具体工厂角色:它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。

3)抽象产品角色:它是具体产品继承的父类或者是实现的接口。在C++中一般由抽象类来实现。

4)具体产品角色:所创建的对象就是此角色的实例。在C++中由具体的类来实现。

  工厂方法模式使用继承自抽象工厂角色的多个子类来代替简单工厂模式中的“上帝类”。正如上面所说,这样便分担了对象承受的压力;而且这样使得结构变得灵活 起来——当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同来生成,那么就可以被客户使用,而不必去修改任何已有的代码。可以看出工厂角色的结构也是符合开闭原则的

代码如下:

  1 /*
  2 @author CodingMengmeng
  3 @datetime:2016-9-29 18:25:08
  4 @description:Factory Method Pattern.
  5 */
  6 #include <iostream>
  7 #include "tchar.h"
  8 using namespace std;
  9
 10 //抽象产品角色
 11 //定义了一个抽象类
 12 class CBMW{
 13 public:
 14     CBMW(){}
 15     ~CBMW(){}
 16     virtual void getStyle(void) = 0;
 17 };
 18
 19 //具体产品角色
 20 //子类1
 21 class CBMW320 :public CBMW{
 22 public:
 23     CBMW320()
 24     {
 25     }
 26     ~CBMW320(){};
 27     void getStyle(void)
 28     {
 29         cout << "Produce -->BMW320" << endl;
 30     }
 31 };
 32 //子类2
 33 class CBMW523 :public CBMW{
 34 public:
 35     CBMW523()
 36     {
 37     }
 38     ~CBMW523(){};
 39     void getStyle(void)
 40     {
 41         cout << "Produce -->BMW523" << endl;
 42     }
 43
 44 };
 45
 46 //抽象工厂角色
 47 class CFactory{
 48 public:
 49     CFactory()
 50     {
 51     }
 52     ~CFactory()
 53     {
 54     }
 55     virtual CBMW* createBMW(void) = 0;
 56
 57 };
 58
 59 //具体工厂角色
 60 //工厂1
 61 class CFactoryBMW320 :public CFactory{
 62 public:
 63     CFactoryBMW320()
 64     {
 65     }
 66     ~CFactoryBMW320()
 67     {
 68     }
 69
 70     CBMW* createBMW(void)
 71     {
 72         return new CBMW320();
 73     }
 74 };
 75
 76 //工厂2
 77 class CFactoryBMW523 :public CFactory{
 78 public:
 79     CFactoryBMW523()
 80     {
 81     }
 82     ~CFactoryBMW523()
 83     {
 84     }
 85     CBMW* createBMW(void)
 86     {
 87         return new CBMW523();
 88     }
 89 };
 90 //客户操作
 91 int _tmain(int argc, _TCHAR** argv)
 92 {
 93     CFactory* factoryBMW320 = new CFactoryBMW320();//new一个生产BMW320的工厂
 94     CBMW* bmw320 = factoryBMW320->createBMW();//生产BMW320
 95     bmw320->getStyle();
 96
 97     CFactory* factoryBMW523 = new CFactoryBMW523();//new一个生产BMW523的工厂
 98     CBMW* bmw523 = factoryBMW523->createBMW();//生产BMW523
 99     bmw523->getStyle();
100
101     return 0;
102
103 }

运行结果:

  

六、总结

  总的来说,工厂方法模式是一个很好的设计模式,它遵循了一个“尽可能让事情保持抽象”的原则,松耦合的设计原则也能够很好地符合开闭原则,将类的实例化推迟到子类,同时也摒弃了简单工厂模式的缺点

  但是同时工厂模式也有一些缺点,每次我们为工厂方法添加新的产品时就要编写一个新的产品类,同时还要引入抽象层,当产品种类非常多时,会出现大量的与之对应的工厂对象,这必然会导致类结构的复杂化,所以对于简单的情况下,使用工厂方法模式就需要考虑是不是有些“重”了。

       

时间: 2024-10-07 22:13:14

(转)设计模式(五)简单工厂模式+工厂方法模式的相关文章

23种设计模式(6):模版方法模式

定义:定义一个操作中算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变算法的结构即可重定义该算法中的某些特定步骤. 类型:行为类模式. 类图: 事实上,模版方法是编程中一个经常用到的模式.先来看一个例子,某日,程序员A拿到一个任务:给定一个整数数组,把数组中的数由小到大排序,然后把排序之后的结果打印出来.经过分析之后,这个任务大体上可分为两部分,排序和打印,打印功能好实现,排序就有点麻烦了.但是A有办法,先把打印功能完成,排序功能另找人做. abstract class AbstractS

23中设计模式----------模版方法模式

模板方法模式: 模板方法模式,就是定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构可重新定义该算法的某些特定步骤. 简而言之,就是定义一个抽象类,在该抽象类中,有一些需要子类特定实现的方法,和一个基本已经实现不改变的方法,而在这个固定的方法中调用那些需要子类实现的方法,从而达到一些步骤延迟到子类中. 所以,在模板方法模式中一般有两类方法: 1,基本方法. 该方法是由子类实现的,并且在模板方法被调用. 2,模板方法. 一般是一个具体的方法,实现对基本方法的调度,

设计模式之模版方法模式

1.模版方法模式简介: a.模版方法模式的简单介绍: -  模版方法模式是编程中经常用到模式.它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现.这样,新的子类可以在不改变一个算法结构的前提上重新定义该算法的某些特定步骤. b.核心:处理某个流程中的代码已经都具备,但是其中某个节点的代码暂时不能确定.因此,我们采用模版方法模式,将这个节点的代码实现转移给子类中完成.即:处理步骤父类中定义好,具体实现延迟到子类中定义. 2.简单的代码演示: 在 BankTemplateMethod 类中添加

25行为型模式之迭代器模式

概念 Iterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式. 在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题.或者说,如果不使用Iterator模式,会存在什么问题. 1.由容器自己实现顺序遍历.直接在容器类里直接添加顺序遍历方法 2.让调用者自己实现遍历.直接暴露数据细节给外部. 以上方法1与方法2都可以实现对遍历,这样有问题呢? 1,容器类承担了太多功能:一方

JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象. 在这些情况,新对象的建立就是一个 "过程",不仅是一个操作,像一部大机器中的一个齿轮传动. 模式的问题:你如何能轻松方便地构造对象实例,而不必关心构造对象实

iOS设计模式——工厂方法(简单工厂模式,工厂方法模式, 抽象工厂模式)

1. 简单工厂模式 如何理解简单工厂,工厂方法, 抽象工厂三种设计模式? 简单工厂的生活场景,卖早点的小摊贩,他给你提供包子,馒头,地沟油烙的煎饼等,小贩是一个工厂,它生产包子,馒头,地沟油烙的煎饼.该场景对应的UML图如下所示: 图1:简单工厂模式UML图 简单工厂模式的参与者: 工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象. 抽象产品(Abstract Product)角色: 是工厂模式所创建对象的父类或是共同拥有的接口.可是抽象类或接口. 具体产品(Conc

PHP面向对象-设计模式 单例模式 简单工厂模式 工厂方法模式

1.单例模式 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 要实现每一个类只有一个实例,就需要对实例化进行限制. 单例模式实现要点: ① 构造函数私有化,不允许使用new关键字创建对象  ② 对外提供获取对象的方法.在方法中判断对象是否为空,如果为空则创建对象并返回,如果不为空则直接返回  ③ 实例对象的属性以及获取对象的方法必须是静态的  ④ 之后,创建对象只能使用我们提供的静态方法. 

设计模式- 简单工厂模式、工厂方法模式及其比较

简单工厂模式及实例 前言工大有许多同学是做java的,大家都知道java最大的优点是它的完全OO化和它在多年的发展过程中吸收和总结了许多先进的框架与模式,其中工厂模式就是最常用的模式之一.下面我想将我在学习和实践过程中对工厂模式的认识与了解介绍给大家.由于笔者能力限制,在实践中也没参与过什么大的项目,笔者参与过的项目用到的工厂模式主要是简单工厂模式(Simple Factory)和工厂方法模式(Factory Method),所以笔者在本文主要介绍的是这两种模式.准备知识在OO设计领域,我们知道

设计模式系列——三个工厂模式(简单工厂模式,工厂方法模式,抽象工厂模式)

原文地址:http://blog.chinaunix.net/uid-25958655-id-4243289.html 简单工厂模式 当需要加法类的时候,调用工厂类的CreateOperate(),要指定制造的Product 例如在大话设计模式P11给的运算工厂例子: public static Operation createOperate(string operate) { Operation oper = null; 12 switch (operate) { case "+":