简单工厂 VS 工厂方法 VS 抽象工厂

         说到设计模式,自然少不了简单工厂模式,工厂方法和抽象工厂这三姐妹。它们之间可谓是各有所长,术业专攻啊!这篇博客来简单的梳理一下三者之间的关系。

那么工厂又是什么意思呢?结合三者的特点,我认为可以这样理解:工厂可以看做一个特殊的类,在这个类中专门负责生产一系列产品(对象)的一个集合就可以成为工厂。

那么上述三种模式之间究竟是怎样的关系呢?各自又有什么优缺点呢?

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

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

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 ;
        }

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

例如:

oper= OperationFactory.createOperate("+");

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

2、工厂方法模式

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

看一段代码:

    interface IFactory //定义一个接口
    {//非静态                                                                                                                           Operation CreateOperation();

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

    class SubFactory:IFactory
    {
        public Operation CreateOperation()
        {
            return new OperationSub();
        }
    }

其余代码类似略。

     通过工厂方法模式,我们可以发现,如果现在再增加一个运算符的话,我们只需要额外增加一个运算符子类和实现接口的子类就好了,而不用去对已经写好的类进行修改了。可见与简单工厂相比,工厂方法模式遵循了开放——封闭原则:即对外扩展,对内封闭。

还有一个小小的区别:在简单工厂中用static声明方法为静态方法,而工厂方法中却未用到静态方法,原因是:在简单工厂中由于不需要子类进行继承,所以使用静态方法可以避免实例化,可以用类来直接调用方法。而在工厂方法中由于存在继承关系,所以不能使用静态方法

二、 工厂方法 VS 抽象工厂

      我认为其实这二者本属于一类。

      最主要的区别是:

      工厂方法:涉及到的是只需定义一个产品类和一个对象接口,可以派生出多个子类。

      而抽象工厂:定义一系列即多个产品类和多个对象接口,分别派生出多个子类。

     这里,不多做解释。

三、简单工厂 VS 抽象工厂 

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

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

如图,如果此时,我们想要在增加一个项目表Project时,必须增加项目接口,SqlserverProject和AccessProject的类同时,还必须修改企业两个工厂,在两个工厂中增加实例化Project的项,造成代码维护量增加。

此时,如果我们把IFactory抽象工厂用一个DataAccess来代替,同时增加一个字符串变量,利用简单工厂来实例化字符串变量中所指定的数据库。

简单工厂方法的类图如下:

当然,我们可以看出来,利用简单工厂方法,虽然改动相对少了,但是仍然违背了开放——封闭原则,因为在增加其他表时,仍需要改动DataAccess中的分支语句,所以,对于简单工厂和抽象工厂方法二者应该酌情使用,二者都有自己的优点和缺点,我们应该根据具体情况具体分析。

当然为了进一步改进,大话设计模式中还提到了利用“反射”和配置文件的技术。总之,设计模式是一门艺术,只有更好,没有最好!

 

 

 

    

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值