`
holoblog
  • 浏览: 1221081 次
博客专栏
E0fcf0b7-6756-3051-9a54-90b4324c9940
SQL Server 20...
浏览量:18856
文章分类
社区版块
存档分类
最新评论

解读设计模式----简单工厂模式(SimpleFactory Pattern),你要什么我就给你什么

 
阅读更多

本文首发于博客园,地址:http://www.cnblogs.com/beniao/archive/2008/08/09/1263318.html

一、模式概述

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现,学习了此模式可以为后面的很多中模式打下基础。那好,我们就来了解下什么是简单工厂模式?

我们来分析一个现实生活中的案例,每天早晨起床洗唰后是干什么呢?吃早餐(这里只针对在外吃早餐的上班族)、坐车(我是穷人只有坐公交,当然很多有钱人都自己有车,这里不考虑这些)去公司上班、是这样的吗?OK,下面就来分析下吃早餐中的故事,大家先看看下面这个图:

当我们在买早餐的时候,早餐店里都卖得写什么呢?这点你有注意吗?众多食品摆在那里,你只对营业员说你要何种食品,他便会知道给你拿什么样的食品给你,这说明什么呢?如果用面向对象的思想来理解的话,营业员在这里就充当了一个工厂的角色,他负责根据你的请求返回你需要的食品对象。而这一点正是简单工厂模式的意图。

二、模式意图

简单工厂模式根据提供给他的数据,返回几个可能类中的一个类的实例。

三、模式UML图

下面是简单工厂模式的示意性UML图:

如上图,简单工厂模式UML我画了两种,详细如下:

① 只有一个产品对象的简单工厂模式。

② 带有一个抽象产品对象的简单工厂模式。

四、模式参与者

工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象。

抽象产品(AbstractProduct)角色: 是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。

具体产品(ConcreteProduct)对象:工厂模式所创建的对象都是这个角色的实例。

五、模式实现

我们通过上面的分析,已经清晰的知道了工厂模式中的各种角色和职责,那工厂模式通过代码是怎么实现的呢?OK,下面将继续分析上面的吃早餐中的故事,做一个简单的示例实现。

1、首先我们来看看只有一个产品对象的简单工厂模式的实现。其实这很好理解,就当店里只卖一种食品,这里以馒头为例。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1///<summary>
2///馒头
3///</summary>
4publicclassSteamedBread
5{
6///<summary>
7///构造方法
8///</summary>
9publicSteamedBread()
10{}
11
12///<summary>
13///销售价格
14///</summary>
15privatedoubleprice=0.5;
16publicdoublePrice
17{
18get{returnprice;}
19set{price=value;}
20}
21}

OK,产品对象建立好了,下面就是创建工厂(Factory)对象了。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1///<summary>
2///工厂角色
3///</summary>
4publicclassFactory
5{
6///<summary>
7///创建一个馒头(SteamedBread)对象
8///</summary>
9///<returns></returns>
10publicstaticSteamedBreadCreateInstance()
11{
12returnnewSteamedBread();
13}
14}

此时,客户端可以这样来调用:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1publicclassClient
2{
3publicstaticvoidMain(string[]args)
4{
5//通过工厂创建一个产品的实例
6SteamedBreadsb=Factory.CreateInstance();
7Console.WriteLine("馒头{0}元一个!",sb.Price);
8}
9}

如上就完成了一个简单工厂模式的简单实现,一个产品和一个工厂,工厂负责创建这个产品。但是者种实现有一定的缺陷,为每一种产品创建一个静态方法来完成产品对象的创建,如果有多个产品则需要定义多个静态方法分别返回不同的对象,用设计原则来说的话这样的实现不符合依赖倒置原则(DIP)。如果系统里只有一个单独的产品对象,那么采用这种实现是完全可以的。UML图如下:

2、带抽象产品(AbstractProduct)角色的简单工厂模式实现

从上面分析中得知,这种实现得为每一种产品创建一个静态方法来完成产品对象的创建。虽然带有简单工厂的性质,但是又好象不能够完全体现出简单工厂模式的意图。简单工厂的意图是:根据提供给他的数据,返回几个可能类中的一个类的实例根据意图出发进行分析,要实现完全满足简单工厂模式意图的程序,也就得根据提供给工厂的数据,让工厂根据这个数据来进行判断,然后返回相应的对象。OK,看看是下面这样的吗?

示意性代码如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1///<summary>
2///食品接口----扮演抽象产品角色
3///</summary>
4publicinterfaceIFood
5{
6///<summary>
7///每种食品都有销售价格,这里应该作为共性提升到父类或是接口来
8///由于我们只需要得到价格,所以这里就只提供get属性访问器
9///</summary>
10doubleprice{get;}
11}
12------------------------------------------------------------------------------------
13///<summary>
14///馒头
15///</summary>
16publicclassSteamedBread:IFood
17{
18///<summary>
19///构造方法
20///</summary>
21publicSteamedBread()
22{}
23
24publicdoubleprice
25{
26get
27{
28return0.5;
29}
30}
31}
32------------------------------------------------------------------------------------
33///<summary>
34///包子
35///</summary>
36publicclassSteamedStuffed:IFood
37{
38publicSteamedStuffed()
39{}
40
41///<summary>
42///销售价格
43///</summary>
44publicdoubleprice
45{
46get
47{
48return0.6;//0.6元一个
49}
50}
51}
52------------------------------------------------------------------------------------
53///<summary>
54///工厂角色
55///</summary>
56publicclassFactory
57{
58///<summary>
59///创建一个馒头(SteamedBread)对象
60///</summary>
61///<returns></returns>
62publicstaticIFoodCreateInstance(stringkey)
63{
64if(key=="馒头")
65{
66returnnewSteamedBread();
67}
68else
69{
70returnnewSteamedStuffed();
71}
72}
73}
74------------------------------------------------------------------------------------
75publicclassClient
76{
77publicstaticvoidMain(string[]args)
78{
79//通过工厂创建一个产品的实例
80IFoodfood=Factory.CreateInstance("馒头");
81Console.WriteLine("馒头{0}元一个!",food.price);
82
83food=Factory.CreateInstance("包子");
84Console.WriteLine("包子{0}元一个!",food.price);
85}
86}

此时的设计就已经完全符合简单工厂模式的意图了。顾客(Client)对早餐店营业员(Factory)说,我要“馒头”,于是营业员便根据顾客所提供的数据(馒头),去众多食品中找,找到了然后就拿给顾客。

3、模式的演变实现

有些情况下Simple Factory可以由抽象产品角色扮演,一个抽象产品类同时是子类的工厂。也就是说,抽象产品角色扮演两种角色和职责,出了基本的定义还还兼任工厂角色的职责,负责产品的创建工作。这里我们在上面的例子基础上适当修改一下OK了,新建立一个抽象类(Evolution):

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1///<summary>
2///兼任抽象产品角色和工厂角色两种角色
3///</summary>
4publicabstractclassEvolution
5{
6///<summary>
7///共性字段
8///</summary>
9privatedoubleprice;
10publicdoublePrice
11{
12get{returnprice;}
13set{price=value;}
14}
15
16
17publicstaticEvolutionCreateInstance(stringkey)
18{
19if(key=="馒头")
20{
21returnnewSteamedBread();
22}
23else
24{
25returnnewSteamedStuffed();
26}
27}
28}

那现在,具体的产品对象的设计也应该修改了,把原来实现于IFood接口改为继承此抽象类,如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1publicclassSteamedBread:Evolution
2{
3publicSteamedBread()
4{
5this.Price=0.5; //在构造方法里初始话属性的值
6}
7}
8
9publicclassSteamedStuffed:Evolution
10{
11publicSteamedStuffed()
12{
13this.Price=0.6;
14}
15}

通过上面的演化,此时客户端的调用如下:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1publicclassClient
2{
3publicstaticvoidMain(string[]args)
4{
5Evolutionel=Evolution.CreateInstance("包子");
6Console.WriteLine("包子{0}元一个!",el.Price);
7}
8}

UML草图如下:

在实际的开发中,这种演化是很适用的,可以说是一种编程技巧吧。

4、模式的其他演变

如果系统中只有唯一的一个具体产品对象,那么可以省略抽象产品角色。这一种其实也就是本钱前面的第一种模式实现。

如果抽象产品角色省略,那么工厂角色就可以与具体产品角色合并。也就是说一个产品类就是自身的工厂。这样把原有三个独立的角色:抽象产品角色、具体产品角色和工厂角色合并为一个,这个类自己负责创建自己的实例。

注:以上演变可以从上面的程序代码中直接修改而来,这里我就不贴代码了。

六、模式优缺点

工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。

当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。

系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。

七、相关模式

工厂方法模式:每个产品由一个专门的工厂来负责创建。是一种只有唯一一个产品的实现,带有简单工厂的性质。

抽象工厂模式:大致和工厂方法相同。

单例模式:单例的实现和上面模式演变中的最后一种很相似,只要把构造器私有便OK。

八、参考资料

Addison-Wesley,1995,p.185. 中文版:《设计模式:可复用的面向对象软件的基础》 李英军等译.

Alan Sharroway & James r.Trott.中文版:《设计模式精解

张逸 著《软件设计精要与模式》

分享到:
评论

相关推荐

    Simple Factory Pattern.rar【GoF的简单工厂模式(C#源码)】

    简单工厂(Simple Factory)模式又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通常它根据自变量的不同返回不同的类的实例。 简单工厂模式的实质是由一个工厂类根据传入的参量,动态决定...

    JAVA设计模式(01):创建型-工厂模式【简单工厂模式】(Simple Factory)

    JAVA设计模式(01):创建型-工厂模式【简单工厂模式】(Simple Factory)

    C#设计模式-吕震宇

    本资料来源于吕震宇博客...C#设计模式(5)-Factory Method Pattern C#设计模式(4)-Simple Factory Pattern C#设计模式(3) - 设计原则(2) C#设计模式(2) - 设计原则(1) C#设计模式(1) - 面向对象基本概念复习

    设计模式 创建型模式 Simple Factory模式(简单工厂)

    Simple Factory模式: 定义创建对象的接口,并封装对象的创建。 一般情况下,我们为了提高内聚和松耦合,经常会使用多态来处理一些问题。抽象出一些类的公共接口作为抽象基类或者接口。这样的话,我们将会面临一个...

    java工厂模式SimpleFactory

    java工厂模式SimpleFactory 一个简单的java Bean工厂模式SimpleFactory

    java 设计模式 Facade外观模式 Simple Factory 简单工厂模式

    java 设计模式 Facade外观模式 Simple Factory 简单工厂模式,代码有点罗嗦,不过可移植性很强

    design-pattern-java.pdf

    六个创建型模式 简单工厂模式-Simple Factory Pattern 工厂三兄弟之简单工厂模式(一) 工厂三兄弟之简单工厂模式(二) 工厂三兄弟之简单工厂模式(三) 工厂三兄弟之简单工厂模式(四) 工厂方法模式-Factory ...

    36种最新设计模式整理

    Design Pattern: Simple Factory 模式 Design Pattern: Abstract Factory 模式 Design Pattern: Builder 模式 Design Pattern: Factory Method 模式 Design Pattern: Prototype 模式 Design Pattern: Singleton...

    设计模式 t01SimpleFactory

    设计模式 t01SimpleFactory

    工厂模式--简单工厂模式

    Simple Factory Pattern 工厂角色:是简单工厂的核心,他负责实现创建所有实例内部逻辑.工厂类可以被外界直接调用,创建所需的产品对象 抽象产品角色:是简单工厂模式所创建的所有对象父类,他负责描述所有实例所共有的...

    C#设计模式.PDF

    C#设计模式(5)-Factory Method Pattern 30 一、 工厂方法(Factory Method)模式 30 二、 Factory Method模式角色与结构: 30 三、 程序举例: 31 四、 工厂方法模式与简单工厂模式 33 五、 Factory Method模式...

    Java设计模式之工厂模式(Factory)

    1. 简单工厂模式(Simple Factory) 2. 工厂方法模式(Factory Method) 3. 抽象工厂模式(Abstract Factory) 这三种模式从上到下逐步抽象,并且更具一般性。还有一种分类法,就是将简单工厂模式看为工厂方法模式的一...

    C#设计模式大全

    C#设计模式(5)-Factory Method Pattern 一、 工厂方法(Factory Method)模式 二、 Factory Method模式角色与结构: 三、 程序举例: 四、 工厂方法模式与简单工厂模式 五、 Factory Method模式演化 六、 ...

    简单工厂模式

    java设计模式 简单工厂模式详解 simple factory static pattern

    Java设计模式简单工厂模式

    Java设计模式之一简单工厂模式(SimpleFactory)源码

    calculator-of-Simple-Factory-Pattern.rar_factory

    本代码利用简单工厂模式来编写一个简单的计算器程序。重点在意设计模式。程序扩展性强。

    Python设计模式之简单工厂模式实例详解

    简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 下面使用简单工厂模式实现一个简单的四则运算 #!/usr/bin/env python # -*- coding:utf-8 ...

    .net简单工厂模式实例源代码

    简单工厂模式(Simple Factory Pattern) .net简单工厂模式实例源代码

    net简单工厂模式实例源代码

    简单工厂模式(Simple Factory Pattern) .net简单工厂模式实例源代码

    C# 简单工厂 SimpleFactory.rar

    SimpleFactory.rar QQ:292258449

Global site tag (gtag.js) - Google Analytics