再次回顾设计模式——工厂三姐妹

  设计模式可谓再熟悉不过了,工厂三姐妹是设计模式中最常见的,也是面试中最常问的,但是就在昨天联想面试的时候面试官问我工厂方法和抽象工厂的区别,我心里特别明白两者之间的关系,但是就是用语言组织不起来,说了半天面试官也只能听懂个大概。还是平时总结的少,今天我们重新回顾一下这三个设计模式。

  工厂是什么意思呢?结合三者的特点,我认为可以这样理解:工厂可以看做一个特殊的类,在这个类中专门负责生产一系列产品(对象)的一个集合就可以成为工厂。
那么上述三种模式之间究竟是怎样的关系呢?各自又有什么优缺点呢?

一、简单工厂模式 VS 工厂方法模式

1、先来看一个简单工厂的一段代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;">public class OperationFactory
    {
        //声明一个方法用来实例化,可是为什么要用静态方法呢                                            public  static Operation createOperate(string operate)                              {
            Operation oper = null;
            switch (operate )
            {
                  //通过分支语句对子类进行实例化                                                          case "+":
                    oper = new OperationAdd();
                     break;
                case "-":
                    oper = new OperationSub();
                    break;
                case "*":
                    oper=new OperationMul ();
                    break;
                case "/":
                    oper =new OperationDiv ();
                    break;  

            }
            return oper ;
        } </span>

  通过代码我们可以看出,在简单工厂中,可以讲多种需要实例化的对象在一个分支结构中一次性的完成。具体的选择要留给客户端去做。
例如:

<span style="font-family:KaiTi_GB2312;font-size:18px;">oper= OperationFactory.createOperate("+");</span>

那我们继续扩展,当我们想要在程序中增加一种算法符号,这时,我们必须对简单工厂中的分支语句进行修改,这样其实就违背了设计模式中的开放——封闭原则。为了避免对内修改,我们再来看一下工厂方法模式。

2、工厂方法模式

       核心思想:创建一个接口,子类去实现这个接口,同时,根据子类来决定究竟要实例化哪个对象。
看一段代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;"> interface IFactory //定义一个接口
    {//非静态                                                                                                                           Operation CreateOperation();  

    }
    class AddFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new OperationAdd();//子类j决定具体对哪个子类进行实例化
        }
    }  

    class SubFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new OperationSub();
        }
    }</span>

其余代码类似略。
   通过工厂方法模式,我们可以发现,如果现在再增加一个运算符的话,我们只需要额外增加一个运算符子类和实现接口的子类就好了,而不用去对已经写好的类进行修改了。可见与简单工厂相比,工厂方法模式遵循了开放——封闭原则:即对外扩展,对内封闭。
还有一个小小的区别:在简单工厂中用static声明方法为静态方法,而工厂方法中却未用到静态方法,原因是:在简单工厂中由于不需要子类进行继承,所以使用静态方法可以避免实例化,可以用类来直接调用方法。而在工厂方法中由于存在继承关系,所以不能使用静态方法

二、 工厂方法 VS 抽象工厂

      我认为其实这二者本属于一类。
      最主要的区别是:
      工厂方法:涉及到的是只需定义一个产品类和一个对象接口,可以派生出多个子类。
      而抽象工厂:定义一系列即多个产品类和多个对象接口,分别派生出多个子类。
     这里,不多做解释。

三、简单工厂 VS 抽象工厂

    在抽象工厂中可以定义多个产品类和对象接口,可是,如果我们想要在此基础上多加一个产品,那么此时,需要增加的类就会很多,同时还需要去更改涉及到的各个工厂。这其实无形中就已经增加了代码的维护量。对于编程来说又是一个不好的兆头。那么有什么办法可以改进它呢?其实,简单工厂可以弥补这个缺陷。

举一个大话设计模式中的例子:创建数据库:SqlServer和Access两类,同时包含IUser和IDepartment两张表如果用抽象工厂方法来设计如图:

  如图,如果此时,我们想要在增加一个项目表Project时,必须增加项目接口,SqlserverProject和AccessProject的类同时,还必须修改企业两个工厂,在两个工厂中增加实例化Project的项,造成代码维护量增加。
此时,如果我们把IFactory抽象工厂用一个DataAccess来代替,同时增加一个字符串变量,利用简单工厂来实例化字符串变量中所指定的数据库。
简单工厂方法的类图如下:

  当然,我们可以看出来,利用简单工厂方法,虽然改动相对少了,但是仍然违背了开放——封闭原则,因为在增加其他表时,仍需要改动DataAccess中的分支语句,所以,对于简单工厂和抽象工厂方法二者应该酌情使用,二者都有自己的优点和缺点,我们应该根据具体情况具体分析。
当然为了进一步改进,大话设计模式中还提到了利用“反射”和配置文件的技术。总之,设计模式是一门艺术,只有更好,没有最好!

时间: 2024-09-20 12:29:06

再次回顾设计模式——工厂三姐妹的相关文章

再次回顾设计模式——策略模式

  设计模式之前是学过的,这次报软考既是复习又是提高.软考需要通过java学习设计模式,之前学的虽然是C#,但设计模式的思想是一样的.话不多说直奔主题,下面先了解一下什么事策略模式.   策略模式定义了算法家族,分别封装起来,让它们之间可以互相转换,此模式让算法的变化不会影响到使用算法的客户.   举个例子:   现在有一个鸭子父类,我们需要它的之类有绿头鸭.红头鸭.只需要在父类里面写一个虚方法display然后让子类去重写,绿头鸭的display就实现绿色的头,红头鸭就实现红色的头.现在让所有

Java设计模式(三—四)----工厂模式

Java设计模式 工厂模式 一.引言 二.分类 三.简单工厂模式 四.工厂方法模式 五.抽象工厂模式 六.和工厂方法模式区别 七.总结 工厂模式 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题.举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象.在这些情况,新对象的建

设计模式(三)建造者模式Builder(创建型)

设计模式(三)建造者模Builder(http://blog.csdn.net/hguisu/article/details/7518060) 1. 概述        在软件开发的过程中,当遇到一个"复杂的对象"的创建工作,该对象由一定各个部分的子对象用一定的算法构成,由于需求的变化,复杂对象的各个部分经常面临剧烈的变化,但将它们组合在一起的算法相对稳定.        例子1:买肯德基        典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡.炸鸡.可乐和玩具

云计算设计模式(三)——补偿交易模式

云计算设计模式(三)--补偿交易模式 撤消由一系列步骤,它们共同限定了最终一致性操作中,如果一个或多个步骤失败执行的工作.按照最终一致性模型,业务实现复杂的业务流程和工作流的云托管的应用程序中很常见. 背景和问题 在云中运行的应用程序频繁修改数据.此数据可跨在各种地理位置的所保持的数据源的一个品种传播.为了避免争用,并提高在分布式环境中,例如这样的性能,应用程序不应该试图提供强事务一致性.相反,应用程序应该实现最终一致性.在该模型中,一个典型的业务操作由一系列的独立的步骤.而正在执行这些步骤的系

跟屌丝大哥学习设计模式--工厂方法模式

东汉<风俗通>记录了一则神话故事:"开天辟辟,未有人民,女娲搏,黄土作人--",讲述的内容就是大家非常熟悉的女娲造人的故事.开天辟地之初,大地上并没有生物,只有苍茫大地,纯粹而洁净的自然环境,寂静而又寂寞,于是女娲决定创造一个新物种(即人类)来增加世界的繁荣,怎么制造呢?       别忘了女娲是神仙,没有办不到的事情,造人的过程是这样的:首先,女娲采集黄土捏成人的形状,然后放到八卦炉中烧制,最后放置到大地上生长,工艺过程是没有错的,但是意外随时都会发生:       第一

[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

[Head First设计模式]山西面馆中的设计模式--装饰者模式 [Head First设计模式]山西面馆中的设计模式--观察者模式 [Head First设计模式]山西面馆中的设计模式--建造者模式 引言 今天是冬至,去饺子馆吃饺子,看他们店里面的水饺种类挺多,在等待中,在想是不是可以用设计模式模拟一下,生产饺子的过程,正好最近也在看工厂模式,也就现学现卖了.当然,实现的方式很多,只是一个例子而已.祝大家冬至,多多吃水饺..... 对象创建的问题? 我们应该面向接口编程而不是面向实现编程,因

Head First 设计模式-工厂模式的疑问?

问题描述 HeadFirst设计模式里的工厂模式那一章,举的例子,是如何从简单工厂模式过渡到工厂方法模式的.在那个例子中,两个模式完成的功能完全相同的吧? 解决方案 解决方案二:有没有源代码解决方案三:简单工厂适合于工厂类负责创建的对象比较少:客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心:简单工厂很容易违反高内聚低耦合原则,因此一般只在很简单的情况下应用如果你的产品是多变的,那么使用简单工厂就不合适了,因为你需要经常修改工厂类,而如果使用工厂方法模式你只需要实现抽象工厂即可,不需要

.NET设计模式-工厂方法模式(Factory Method)

工厂方法模式(Factory Method) --.NET设计模式系列之五 Terrylee,2004年1月2日 概述 在软件系统中,经常面临着"某个对象"的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.如何应对这种变化?提供一种封装机制来隔离出"这个易变对象"的变化,从而保持系统中"其它依赖该对象的对象"不随着需求的改变而改变?这就是要说的Factory Method模式了. 意图 定义一个用户创

重温设计模式(三)——职责链模式(chain of responsibility)

一.写在前面的 这么多的设计模式,我觉得职责链是我第一次看上去最简单,可是回想起来却又最复杂的一个模式. 因此,这个文章我酝酿了很久,一直也没有胆量发出来,例子也是改了又改,可是仍然觉得不够合理.所以希望各位多多指教. 二.什么是链 文章伊始,先让我们了解这个最基本的概念,什么是链. 我给链下了这样的定义: 1.链是一系列节点的集合. 2.链的各节点可灵活拆分再重组. 三.何为职责链 职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着