设计模式 之 简单工厂与工厂方法

来源:互联网 发布:com域名免备案 编辑:程序博客网 时间:2024/05/02 01:55

    最近开始学习《大话设计模式》,作者以通俗的方式来讲解,还有故事情节,幽默的对白,给人耳目一新的感觉。非常喜欢作者的这种步步深入,循循善诱的方式。学习了就要总结,总结的时候自己也学着作者的方式,以自己生活中的小例子来实现我们的设计模式。下面就开始我们的第一讲《简单工厂和工厂方法》。


    前两天带着一个老乡去吃饭,当然,作为一个四川人,去外边吃饭当然是点我们著名的川菜!下面先用简单工厂来实现一下:


using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace 简单工厂{    //抽象产品类    public abstract class  food    {        public abstract void Show();    }    //具体产品类型    public class huiguorou:food     {        public override void Show()        {            Console.WriteLine("来咯,回锅肉一份!");        }    }    public class mapodoufu:food    {        public override void Show()        {            Console.WriteLine("来咯,麻婆豆腐一份!");        }    }    public class shuizhuroupian:food    {        public override void Show()        {            Console.WriteLine("来咯,水煮肉片一份!");        }    }    public class yuxiangrousi:food    {        public override void Show()        {            Console.WriteLine("来咯,鱼香肉丝一份!");        }    }    //简单工厂    public class foodFacoty    {        public static food CreateFood(string Name)        {            food Food = null;            switch (Name)            {                case "回锅肉":                    Food = new huiguorou();                    break;                case "麻婆豆腐":                    Food = new mapodoufu();                    break;                case "水煮肉片":                    Food = new shuizhuroupian();                    break;                case "鱼香肉丝":                    Food = new yuxiangrousi();                    break;            }            return Food;        }    }    class Program    {        static void Main(string[] args)        {             Console.WriteLine("老板,给我们来份回锅肉!");            Console.WriteLine("再来一份水煮肉片!");            food Food1 = foodFacoty.CreateFood("回锅肉");            Food1.Show();            food Food2 = foodFacoty.CreateFood("水煮肉片");            Food2.Show();             }    }}



简单工厂的类图:

                                                                    



简单工厂的优点
    1.通过IProduct隔离了客户程序与ConcreteProductA的依赖关系,在客户程序视野内根本就没有ConcreteProductA。
    2.即使ConcreteProductA增加、删除方法或属性,也无妨大局,只要按照要求实现了IProduct就可以了,Client无须关心ConcreteProductA的变化。
    3.相对直接写个ConcreteProductA而言,要平白地多写一个工厂出来,尤其需要IProduct频繁变化的时候,客户程序也闲不下来。

简单工厂的局限性
    简单工厂比较优雅的解决了外部new()的问题,它把目标实例的创建工作交给外部的工厂完成,是设计模式化思想一个很不错的引子。但如果应用中需要工厂的类型只有一个,而且工厂的职责又非常单纯——就是一个new()的替代品,类似我们面向对象中普遍的思路,这时候就需要进一步抽象了,于是出现了新的发展:工厂方法模式和抽象工厂模式。

接下来我们就用工厂方法来改进一下上面的代码,利用工厂方法,我们就不需要上面的简单工厂类,而是创建一个抽象工厂,这个抽象工厂有一个生产食物的方法。然后再用具体的工厂继承抽象工厂,并实现产生不同食物的方法。最后我们的客户端代码也就不一样了。


//抽象工厂    public abstract class FoodFactory    {        public abstract food CreateFood();    }    //具体工厂    public class huiguorouFactory : FoodFactory    {        public override food CreateFood()        {            return new huiguorou();        }    }    public class mapodoufuFactory : FoodFactory    {        public override food CreateFood()        {            return new mapodoufu();        }    }    public class shuizhuroupianFactory : FoodFactory    {        public override food CreateFood()        {            return new shuizhuroupian();        }    }    public class yuxiangrousiFactory : FoodFactory    {        public override food CreateFood()        {            return new yuxiangrousi();        }    }    class Program    {        static void Main(string[] args)        {            Console.WriteLine("老板,给我们来份回锅肉!");            Console.WriteLine("再来一份鱼香肉丝");            FoodFactory factory1 = new huiguorouFactory();            food Food1 = factory1.CreateFood();            Food1.Show();            FoodFactory factory2 = new yuxiangrousiFactory();            food Food2 = factory2.CreateFood();            Food2.Show();                    }    }


工厂方法的类图:

                                                                         



下面我们再来看看使用工厂方法模式的场合:
    1.当子类型可能会有很多,以后需要不但增添不同的子类实现时;
    2.当一个系统尚在框架设计阶段,还不知道将来需要实例化哪些具体类时;

    3.系统设计之初不需要具体对象的概念(或者说没有具体对象的概念);


    简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。但问题也就在这里,如果要求加另外一个产品,我们就需要在简单工厂类的方法里加‘Case’的分支条件,修改原有的类。这就违背了开放-封闭原则。工厂方法模式是将工厂类抽象出一个接口(或一个抽象类)。然后所有要生产具体类的工厂,去实现这个接口(或继承这个抽象类)。这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口(或抽象类)和多个具体生成对象的工厂。


    工厂方法模式克服了简单工厂违背开放-封闭原则的缺点,它们都是几种封装了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低客户程序与产品对象的耦合。






19 0
原创粉丝点击