创建型模式中关于工厂的模式

   在创建型模式中,有3中关于工厂的模式,分别是:简单工厂模式,工厂方法模式,抽象工厂模式。这3中模式既有各自的优点,同时,这3中模式又可以逐步演化:如,简单工厂可以演化成工厂方法,工厂方法可以演化成抽象工厂。


  简单工厂到工厂方法

     由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

    另外,当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,造成switch..case过于复杂,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。

   就是说,switch..case这种判断一是增加新类时要修改switch语句,二如果产品太多,又造成switch过于复杂。

    鉴于简单工厂中switch的这两个缺点,所以,提出创建一个单独的类来进行产品的创建。工厂方法定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是将一个类的实例化延迟到其子类。

   例如:

    编写一个计算器,如果用简单工厂来写的话,就要在创建示例的工厂类中写很多switch语句,一旦增加新的运算,就要修改核心的代码,违反了开放封闭的原则。

public class OperationFactory    {
        public static Operation createOperate(string operate)
        {
            Operation oper = null;
            switch (operate)
            {
                case "+":
                    oper = new OperationAdd();
                    break;
                case "-":
                    oper = new Operation();
                    break;
                case "*":
                    oper = new Operation();
                    break;
                case "/":
                    oper = new Operation();
                    break;
            }

            return oper;

        }
 
    }


       但是如果改成用工厂方法来写的话,当增加运算时,只需在多加两个类,虽然没有避免掉判断,但是一旦扩展功能的话,本来是要改工厂类的,而现在修改的确是客户端。虽然增加了类,但是使得扩展更灵活。



 

 总结: 

    工厂方法克服了简单工厂违背开放—封闭原则的缺点,又保持了封装对象创建过程的优点。

   它们都是集中封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户程序与产品对象的耦合。工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。


工厂方法到抽象工厂模式

先来看两种方法访问数据库的结构图:


用工厂方法访问数据库:


接着是抽象工厂访问数据库:



    从图中可以看出当用工厂方法访问数据库的时候,访问的是一张表,而当用抽象工厂访问数据库的时候访问的是两张表。如果去掉抽象工厂方法中访问第二张表的类,可以看出,它们剩下的部分是一样的。、

   所以,从工程方法到抽象工厂,只是涉及到的产品系列多了。

   

简单工厂对抽象工厂的改进

      从简单工厂到工厂方法,为了改进switch的不灵活创建了更多的类,从工厂方法到抽象工厂也是多了类,那么,如果使用抽象工厂时有非常多的product时就会出现问题:比如,现在有100张表,每个表都是一个product,要从access数据库换到sql server数据库,那么,要改动的这句“Ifactoryfacoty=new AccessFactory();”改动100次了,这是件很悲伤的事儿。。这时,我们可以用简单工厂来改进抽象工厂。

   简单工厂最大的弊端就是当增加新的需求时要改进switch,但是如果switch的可选项就是两项,不如,一个公司使用的数据库目前只有access和sql server时,这时,switch语句就是不用被经常改动的,此时,它的缺点恰恰成了它最大的优点,因为相比工厂方法和抽象工厂,它不用创建那么多的类就能很简单的实现选择问题。

  如下结构图:


  



   总的来说,这3种模式都是为了实现选择问题的模式。我们想要做到的就是在程序运行时根据需要做出正确选择,并且当程序日后遇到需求的改动,是非常容易扩展和修改的。

   选择的算法好实现,但是可扩展,易修改却不好实现。为什么不好实现呢?还是因为代码写的太死了。

   想想一起我们学习一门语言的时候,总会学到一个叫做变量的东西。这是个非常好的东西。因为它可以在程序运行时动态的赋值,改动。如果在选择的时候,我们有这样一个变量,只需给它一次初值,以后程序都根据这个变量的值去实例化对象,一旦要改动,只需改动一次就行。那么就会省去判断的麻烦,并且更加灵活。

   这里,就要用到新技术了——反射。


这里,利用反射+字符串拼接,完美实现实例化对象。

   

小结

       1,对于这3种涉及到工厂的方法,它们各有各的优点,要注意它们的使用条件,并不是抽象工厂模式就最好;

     2,有时候,模式的混合使用会有更好的效果;

     3,在设计中,要尽量的封装变化。

   

  

 

 


 

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水田如雅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值