`
12616383
  • 浏览: 51507 次
  • 性别: Icon_minigender_1
  • 来自: 待定
社区版块
存档分类
最新评论

简单工厂模式

阅读更多

、模式概述

     从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现,学习了此模式可以为后面的很多中模式打下基础。那好,我们就来了解下什么是简单工厂模式?
 
     我们来分析一个现实生活中的案例,每天早晨起床洗唰后是干什么呢?吃早餐(这里只针对在外吃早餐的上班族)、坐车(我是穷人只有坐公交,当然很多有钱人都自己有车,这里不考虑这些)去公司上班、是这样的吗?OK,下面就来分析下吃早餐中的故事,大家先看看下面这个图:
                      
     当我们在买早餐的时候,早餐店里都卖得写什么呢?这点你有注意吗?众多食品摆在那里,你只对营业员说你要何种食品,他便会知道给你拿什么样的食品给你,这说明什么呢?如果用面向对象的思想来理解的话,营业员在这里就充当了一个工厂的角色,他负责根据你的请求返回你需要的食品对象。而这一点正是简单工厂模式的意图。
 
二、模式意图
     简单工厂模式根据提供给他的数据,返回几个可能类中的一个类的实例。
 
三、模式UML图     
     下面是简单工厂模式的示意性UML图:
                
     如上图,简单工厂模式UML我画了两种,详细如下:
     ① 只有一个产品对象的简单工厂模式。 
     ② 带有一个抽象产品对象的简单工厂模式。
 
四、模式参与者
      工厂(Factory)角色:接受客户端的请求,通过请求负责创建相应的产品对象。
      抽象产品(AbstractProduct)角色: 是工厂模式所创建对象的父类或是共同拥有的接口。可是抽象类或接口。
      具体产品(ConcreteProduct)对象:工厂模式所创建的对象都是这个角色的实例。
 
五、模式实现
     我们通过上面的分析,已经清晰的知道了工厂模式中的各种角色和职责,那工厂模式通过代码是怎么实现的呢?OK,下面将继续分析上面的吃早餐中的故事,做一个简单的示例实现。
     1、首先我们来看看只有一个产品对象的简单工厂模式的实现。其实这很好理解,就当店里只卖一种食品,这里以馒头为例。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />--> 1 /// <summary>
 2 /// 馒头
 3 /// </summary>
 4 public class SteamedBread
 5 {
 6     /// <summary>
 7     /// 构造方法
 8     /// </summary>
 9     public SteamedBread()
10     { }
11 
12     /// <summary>
13     /// 销售价格
14     /// </summary>
15     private double price=0.5;
16     public double Price
17     {
18         get { return price; }
19         set { price = value; }
20     }
21 }
     
     OK,产品对象建立好了,下面就是创建工厂(Factory)对象了。
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />--> 1 /// <summary>
 2 /// 工厂角色
 3 /// </summary>
 4 public class Factory
 5 {
 6     /// <summary>
 7     /// 创建一个馒头(SteamedBread)对象
 8     /// </summary>
 9     /// <returns></returns>
10     public static SteamedBread CreateInstance()
11     {
12         return new SteamedBread();
13     }
14 }
 
     此时,客户端可以这样来调用:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />-->1 public class Client
2 {
3     public static void Main(string[] args)
4     {
5         //通过工厂创建一个产品的实例
6         SteamedBread sb = Factory.CreateInstance();
7         Console.WriteLine("馒头{0}元一个!", sb.Price);
8     }
9 }
 
     如上就完成了一个简单工厂模式的简单实现,一个产品和一个工厂,工厂负责创建这个产品。但是者种实现有一定的缺陷,为每一种产品创建一个静态方法来完成产品对象的创建,如果有多个产品则需要定义多个静态方法分别返回不同的对象,用设计原则来说的话这样的实现不符合依赖倒置原则(DIP)。如果系统里只有一个单独的产品对象,那么采用这种实现是完全可以的。UML图如下:
                            
 
     2、带抽象产品(AbstractProduct)角色的简单工厂模式实现
     从上面分析中得知,这种实现得为每一种产品创建一个静态方法来完成产品对象的创建。虽然带有简单工厂的性质,但是又好象不能够完全体现出简单工厂模式的意图。简单工厂的意图是:根据提供给他的数据,返回几个可能类中的一个类的实例根据意图出发进行分析,要实现完全满足简单工厂模式意图的程序,也就得根据提供给工厂的数据,让工厂根据这个数据来进行判断,然后返回相应的对象。OK,看看是下面这样的吗?
                          
     示意性代码如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />--> 1 /// <summary>
 2 /// 食品接口----扮演抽象产品角色
 3 /// </summary>
 4 public interface IFood
 5 {
 6     /// <summary>
 7     /// 每种食品都有销售价格,这里应该作为共性提升到父类或是接口来
 8     /// 由于我们只需要得到价格,所以这里就只提供get属性访问器
 9     /// </summary>
10     double price{get;}
11 }
12 ------------------------------------------------------------------------------------
13 /// <summary>
14 /// 馒头
15 /// </summary>
16 public class SteamedBread:IFood
17 {
18     /// <summary>
19     /// 构造方法
20     /// </summary>
21     public SteamedBread()
22     { }
23 
24     public double price
25     {
26         get
27         {
28             return  0.5;
29         }
30     }
31 }
32 ------------------------------------------------------------------------------------
33 /// <summary>
34 /// 包子
35 /// </summary>
36 public class SteamedStuffed:IFood
37 {
38     public SteamedStuffed()
39     { }
40 
41     /// <summary>
42     /// 销售价格
43     /// </summary>
44     public double price
45     {
46         get
47         {
48             return  0.6;  //0.6元一个
49         }
50     }
51 }
52 ------------------------------------------------------------------------------------
53 /// <summary>
54 /// 工厂角色
55 /// </summary>
56 public class Factory
57 {
58     /// <summary>
59     /// 创建一个馒头(SteamedBread)对象
60     /// </summary>
61     /// <returns></returns>
62     public static IFood CreateInstance(string key)
63     {
64         if (key == "馒头")
65         {
66             return new SteamedBread();
67         }
68         else
69         {
70             return new SteamedStuffed();
71         }
72     }
73 }
74 ------------------------------------------------------------------------------------
75 public class Client
76 {
77     public static void Main(string[] args)
78     {
79         //通过工厂创建一个产品的实例
80         IFood food = Factory.CreateInstance("馒头");
81         Console.WriteLine("馒头{0}元一个!", food.price);
82 
83         food = Factory.CreateInstance("包子");
84         Console.WriteLine("包子{0}元一个!", food.price);
85     }
86 }
 
     此时的设计就已经完全符合简单工厂模式的意图了。顾客(Client)对早餐店营业员(Factory)说,我要“馒头”,于是营业员便根据顾客所提供的数据(馒头),去众多食品中找,找到了然后就拿给顾客。
 
     3、模式的演变实现
     有些情况下Simple Factory可以由抽象产品角色扮演,一个抽象产品类同时是子类的工厂。也就是说,抽象产品角色扮演两种角色和职责,出了基本的定义还还兼任工厂角色的职责,负责产品的创建工作。这里我们在上面的例子基础上适当修改一下OK了,新建立一个抽象类(Evolution):
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />--> 1 /// <summary>
 2 /// 兼任抽象产品角色和工厂角色两种角色
 3 /// </summary>
 4 public abstract class Evolution
 5 {
 6     /// <summary>
 7     /// 共性字段
 8     /// </summary>
 9     private double price;
10     public double Price
11     {
12         get { return price; }
13         set { price = value; }
14     }
15 
16 
17     public static Evolution CreateInstance(string key)
18     {
19         if (key == "馒头")
20         {
21             return new SteamedBread();
22         }
23         else
24         {
25             return new SteamedStuffed();
26         }
27     }
28 }
 
     那现在,具体的产品对象的设计也应该修改了,把原来实现于IFood接口改为继承此抽象类,如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />--> 1 public class SteamedBread : Evolution
 2 {
 3     public SteamedBread()
 4     {
 5         this.Price = 0.5;  //在构造方法里初始话属性的值
 6     }
 7 }
 8 
 9 public class SteamedStuffed : Evolution
10 {
11     public SteamedStuffed()
12     {
13         this.Price = 0.6;
14     }
15 }
     
     通过上面的演化,此时客户端的调用如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />[url]http://www.CodeHighlighter.com/[/url]<br /><br />-->1 public class Client
2 {
3     public static void Main(string[] args)
4     {
5         Evolution el = Evolution.CreateInstance("包子");
6         Console.WriteLine("包子{0}元一个!", el.Price);
7     }
8 }
 
     UML草图如下:
                                       
     在实际的开发中,这种演化是很适用的,可以说是一种编程技巧吧。
 
     4、模式的其他演变
     如果系统中只有唯一的一个具体产品对象,那么可以省略抽象产品角色。这一种其实也就是本钱前面的第一种模式实现。
     如果抽象产品角色省略,那么工厂角色就可以与具体产品角色合并。也就是说一个产品类就是自身的工厂。这样把原有三个独立的角色:抽象产品角色、具体产品角色和工厂角色合并为一个,这个类自己负责创建自己的实例。
 
     注:以上演变可以从上面的程序代码中直接修改而来,这里我就不贴代码了。   
 
六、模式优缺点
      工厂类含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。简单工厂模式通过这种做法实现了对责任的分割。
      当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
      系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
 
七、相关模式
      工厂方法模式:每个产品由一个专门的工厂来负责创建。是一种只有唯一一个产品的实现,带有简单工厂的性质。
      抽象工厂模式:大致和工厂方法相同。
      单例模式:单例的实现和上面模式演变中的最后一种很相似,只要把构造器私有便OK。
分享到:
评论

相关推荐

    工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式

    工厂模式分为三种主要类型:简单工厂模式、工厂方法模式和抽象工厂模式。 1. **简单工厂模式** 简单工厂模式是最简单的工厂模式实现,它提供一个静态方法或者类来创建对象,这个类通常被称为“工厂”。用户只需要...

    简单工厂模式-工厂方法模式-抽象工厂模式

    在软件设计模式中,工厂模式是一组非常基础且实用的设计模式,主要分为简单工厂模式、工厂方法模式和抽象工厂模式。这些模式都是为了解决对象创建的问题,通过封装对象的创建过程,使得代码更加灵活,易于扩展和维护...

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

    **简单工厂模式**是软件设计模式中的一种,属于创建型模式。在Java编程中,它是一种用于创建对象的简便方法,将对象的实例化过程封装到一个单独的工厂类中,使得客户端代码无需直接调用具体类的构造函数,而是通过...

    uml 文档 简单工厂模式

    UML文档-简单工厂模式 简单工厂模式是一种专门负责将大量有共同接口的类实例化的模式,而不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。 简单工厂模式的...

    简单工厂模式uml类图

    java设计模式 简单工厂模式uml类图,一张图就让你秒懂简单工厂模式

    简单工厂模式_简单工厂模式_

    简单工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。这种模式使得代码能够将实例化的责任封装起来,使得客户端代码无需关心具体的对象实现,只需要知道一个公共接口即可...

    C#简单工厂模式女娲造人

    "C#简单工厂模式女娲造人"这个标题和描述采用了一种形象的比喻,将创建对象的过程比作神话故事中的女娲造人,以帮助理解简单工厂模式的基本概念。 简单工厂模式是一种创建型设计模式,它的核心思想是提供一个工厂类...

    Android计算器(简单工厂模式)

    **Android计算器(简单工厂模式)** 简单工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在这个模式中,一个单独的类(被称为工厂)负责创建对象,客户端通过调用工厂方法来获取所需的对象,而无需...

    反射简单工厂模式工厂模式

    本文将深入探讨"反射"以及两种常见的工厂模式:"简单工厂模式"和"工厂方法模式",并结合提供的文件名称来解析这些概念。 首先,我们来看"反射"。在Java等面向对象语言中,反射是一种强大的工具,它允许程序在运行时...

    简单工厂模式学习代码

    简单工厂模式是一种设计模式,它是创建型模式的一种,主要用于简化对象的创建过程。在这个模式中,有一个工厂类负责创建特定类型的对象,而客户端通过调用工厂的方法来获取所需的实例,无需关心具体的创建过程。这种...

    简单工厂模式应用

    简单工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。这种类型的设计模式属于类创建模式,因为工厂类是基于类的。在简单工厂模式中,一个工厂类根据传入的参数来决定创建...

    C++制作的简单工厂模式计算器

    **简单工厂模式计算器** 在软件设计模式中,简单工厂模式是一种常用的创建型模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。在这个案例中,"C++制作的简单工厂模式计算器"就是一个运用了简单...

    简单工厂模式之商场收银软件

    简单工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象的最佳方式。在这个模式中,一个专门的类(称为工厂类)负责创建对象,客户端不再直接创建对象,而是通过调用工厂类的方法来得到所需的产品。这种...

    简单工厂模式,工厂方法模式,抽象工厂模式

    本文将深入探讨三种工厂模式:简单工厂模式、工厂方法模式以及抽象工厂模式,并结合源码分析其应用场景和优缺点。 1. 简单工厂模式 简单工厂模式(Simple Factory Pattern)是一种静态工厂方法,它通过一个公共的...

    设计模式之简单工厂模式案例

    简单工厂模式是软件设计模式中的一种创建型模式,它提供了一种创建对象的最佳方式。在简单工厂模式中,一个工厂类负责创建所有相关的对象,而客户端只需要知道具体的产品类型,无需了解如何创建这些对象的细节。这种...

    简单工厂模式.zip

    简单工厂模式是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。这种模式使代码能够将实例化过程封装起来,使得客户端代码无需知道具体的产品类名,只需要知道产品类型即可。在C#中...

    Java简单工厂模式和传统模式实现对比

    Java简单工厂模式是一种设计模式,它是创建型模式的一种,用于将对象的创建过程封装到一个独立的工厂类中,使得客户端代码无需关心具体的对象创建细节,只需要知道如何调用工厂方法即可得到所需的对象。这种模式在...

    java简单工厂模式文档简单汇总

    【Java 简单工厂模式】简单工厂模式是一种创建型设计模式,它的主要思想是提供一个工厂类,根据传入的参数动态地返回一个产品对象。这种模式将对象的创建与对象的使用分离,使得代码更加简洁且易于维护。 在Java中...

Global site tag (gtag.js) - Google Analytics