工厂三姐妹

第一次看到这个名字,感觉很亲切,没想到在设计模式里还有如此温馨的称呼,想到工厂三姐妹,大家肯定会想,恩?三姐妹都是谁?下面小编将带领大家进入设计模式的世界,认识我们最亲爱的工厂三姐妹。

简单工厂模式:

到底要实例化谁,将来会不会增加实例化的对象,比如增加开跟运算,这是很容易变化的地方,应该考虑用一个单独的类来做这个创造实例的过程,这就是工厂。

优点:
1.符合面向对象中的三大特性:封装、继承、多态。
2.有必要的逻辑判断。
3.职责单一,实现简单,且实现了客户端代码与实现代码的解耦合。
缺点:
1.违背开闭原则。
2.不易维护、扩展。
适用场合:
1.工厂类负责创建的对象比较少;
2.客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
3.由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。
代码展示:
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">/// <summary>
    /// 简单工厂类
    /// </summary>
    public class OperationFatory
    {
        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>
客户端应用:
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;"> Operation oper;
 oper = OperationFatory.createOperate("+");
 oper.NumberA = 1;
 oper.NumberB = 2;
 double result = oper.GetResult(); </span></span>
该计算器,客户端不用管该用哪个类的实例,只需要把“+”给工厂,客户端只需要做运算就可以了。但是如果要求平方,那就需要修改原有的类,对修改开放,违背了开放封闭原则。而工厂方法模式恰恰克服了这个缺点。

联系生活:
追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory。

工厂方法模式:

定义:
定义一个创建对象的对象,让子类决定实例化那一个类。工厂方法是一个类的实例化延迟到到子类。
优点:
克服了简单工厂模式违背开闭原则的缺点,保持了封装对象创建过程的优点。
代码展示:
先构建一个工厂接口:
<span style="font-family:SimSun;font-size:18px;"> interface IFactory
        {
            Operation CreateOperation();
        }</span>
然后算法各建一个具体工厂实现接口:
<span style="font-family:SimSun;font-size:18px;"> class AddFactory:IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationAdd();
            }
        }
        class SubFactory:IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationSub();
            }
        }
        class MulFactory:IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationMul();
            }
        }
        class DivFactory:IFactory
        {
            public Operation CreateOperation()
            {
                return new OperationDiv();
            }
        } </span>
客户端代码:
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">static void Main(string[] args)
        {
            IFactory operFactory = new AddFactory();
            Operation oper = operFactory.CreateOperation();
            oper.NumberA = 1;
            oper.NumberB =2;
            double result = oper.GetResult();
        }</span></span>
联系生活:
请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我带着MM到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。

工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,克服了它的缺点。但它不是最好的,还是没有避免修改客户端的代码。利用反射可以解决分支判断的问题,那么我们不得不提到工厂模式中一种特殊的抽象工厂模式。

抽象工厂模式:

定义:
提供一个创建系列相关或相互依赖对象的接口,而无需指定他们具体的类。
优点:
1.可以很方便的切换两个数据库访问的代码。
2.在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。如果你要更改数据库访问,我们只需要更改具体工厂就可以做到。
3.让具体的创建实例过程与客户端分离,客户端是通过他们的额抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
缺点:
若增加功能需要改动的很多,所以用到了反射。
使用场合:
数据库中有很多的表,而SQL Server与Access又是两大不同的分类,所以解决这种涉及到多个产品系列的问题,就用到了抽象工厂模式。

反射+抽象工厂的数据访问程序:
常规写法:
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">IUser result=new SqlserverUser();</span></span>
反射用法:Assembly.Load("程序集名称").CreateInstance("命名空间.类名称")
<span style="font-family:SimSun;font-size:18px;"><span style="font-family:SimSun;font-size:18px;">using System.Reflection;
IUser result=(IUser)Assembly.Load("抽象工厂模式").CreateInstance("抽象工厂模式.SqlserverUser");</span></span>
用反射+配置文件实现数据访问程序:
在配置文件中写清楚数据库,可以不用更改类了。

三者由来:

无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。拿一个生产水杯(cup)的工厂举例:起初,不用工厂模式,我必须在生产水杯之前知道水杯的材料和形状等水杯的所有特征才能生产,这就是我们的new Cup();这个Cup必须是具体的。厂主发现同一形状的被子,只是材料不同,如一个是玻璃(glass)的,一个是瓷(china)的,但是确要两条生产线,显然有资源浪费的嫌疑。现在厂主生产杯子时先不让生产线知道我要产的是玻璃的还是瓷的,而是让它在不知道具体材料的情况下先做它能做的,等到它把模具做好,只需要向其中填充玻璃原料或者瓷原料就可以造出同一形状的具体杯子了。但是很可惜,java并不能new一个抽象的Cup,所以就有了简单工厂模式。原来是Cup cup=new Cup;现在SimpleCupFactory.createCup(String cupName),根据cup的名字生产Cup,而createCup返回的是一个实现了 Cup接口或抽象类的具体Cup。简单工厂模式有一个问题,就是当我现在想生产一个同样形状的铁杯时,工厂里并没有定义相应的处理流程,只能更改createCup方法,这就不合理了。我现在只是想生产铁杯,你只要在最后的时候把玻璃原料换成铁的不就行了吗,干嘛还要更改整条生产线呢?于是就有了工厂模式。原来生产线在生产模具的时候还要考虑是为玻璃杯生产的模具还是为铁杯生产的模具,现在它不用管了。CupFactory.createCup()创建Cup.CupFactory是接口或抽象类。实现它的具体子类会创建符合Cup接口的具体Cup。那么现在厂主想要生产水壶(kettle),用工厂模式就不得不再造一条水壶生产线,能不能在水杯生产线同时生产水壶呢?这就是抽象工厂模式。
 
  
总结:
三种模式各有各的优点,简单工厂模式不符合开放封闭原则故而未归入23种模式中,但有时候为了使程序变得简单,结合简单工厂的优点可以解决很多问题,所以它也不是没用。工厂方法模式是简单工厂模式的进一步抽象和推广。它克服了简单工厂模式不符合开闭原则的缺点,创建对象接口后,子类可告诉父类实例化哪一个,保持了简单工厂模式的优点,降低了耦合。工厂方法模式只有一个产品类,而抽象工厂模式有多个产品类。

感谢您宝贵的时间!




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 17
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值