工厂模式

现在,如果我想要创建一个界面View的实例需要调用View的构造函数:View view=new View();

现在我想要创建3个不同的界面,分别是View1,View2,View3,那么我将在另一个类中调用它们的构造函数。

            View1 view1 = new View1();
            View2 view2 = new View2();
            View3 view3 = new View3();

如果有更多的窗口呢?这样公开的使用new操作符,很容易造成耦合问题。但若创建实例就必须使用new,那么我们如何更好的使用new呢?

简单工厂

其实我们再平时写代码时或许已经有了这样的思想。这许多的View都有很多共同点,假设其中一个便是显示窗口的名称(当然这没有什么实际意义),我们将其抽象为一个接口IView,为了方便,这里的View就是单纯的类,不是真正意义上的Window.

    public interface IView
    {
        void Display();
    }
    public class View1 : IView
    {
        public void Display()
        {
            System.Console.WriteLine("界面1");
        }
    }
    public class View2 : IView
    {
        public void Display()
        {
            System.Console.WriteLine("界面2");
        }
    }
    public class View3 : IView
    {
        public void Display()
        {
            System.Console.WriteLine("界面3");
        }
    }

然后我们把所有实例的创建都放在ViewFactory中:

    public class ViewFactory
    {
        public ViewFactory()
        {
        }

        public static IView CreateView(string viewName)
        {
            switch (viewName)
            {
                case "View1":
                    return new View1(); 
                case "View2":
                    return new View2();
                case "View3":
                    return new View3(); 
                default:
                    return null;
            }
        }
    }

这样便可按需(根据View的名字作为参数)创建实例,并调用显示名称的方法:

    class Program
    {
        static void Main(string[] args)
        {
            ViewFactory.CreateView("View1").Display();
            ViewFactory.CreateView("View2").Display();
            ViewFactory.CreateView("View3").Display();
            System.Console.ReadLine(); 
        }
    }

运行结果:

上面这个就是典型的简单工厂模式了,其实我们平时可能已经有了这样的思想,只是并没有进行更多的总结。通过简单工厂,我们将所有实例化封进另外一个对象,同时通过多态实现了针对接口的编程,而不是直接针对具体类View1等。

如果此时,我还想再增加View4等等,我不仅需要增加View4的界面,还必须修改ViewFactory,增加几句代码:

case "View4":
   return new View4();

增加新界面就必须修改ViewFactory,这明显违背了开-闭原则,这也是简单工厂模式的缺点。

工厂方法模式

由于简单工厂违背了开闭原则,需要在简单工厂的基础上修改一下,就是工厂方法模式(Factory Method),与简单工厂不同的是,创建对象不会集中在同一个类中,而是通过FactoryMethod方法在各个子类中分别实现相应对象的实例。

每个View都会有自己独立的Factory,现在将这多个Factory抽象为接口IFactory:

    public interface IFactory
    {
        IView GetView();
    }

各个独立的Factory,可取得对应的对象实例:

    public class ViewFactory1 : IFactory
    {
        public IView GetView()
        {
            return new View1();
        }
    }
    public class ViewFactory2 : IFactory
    {
        public IView GetView()
        {
            return new View2();
        }
    }

调用,只以View1为例:

    class Program
    {
        static void Main(string[] args)
        {
            IFactory factory = new ViewFactory1();
            IView view = factory.GetView();
            view.Display();
            System.Console.ReadLine();  
        }
    }

结果:

如果需要新增一个View4,需要增加一个ViewFactory4和View4的类,但是不必修改已存在的其他类。

抽象工厂

提供一个创建一系列相关或者事相互依赖对象的接口,而无需指定它们具体的类。

 

也就是说具体工厂生产类似的产品(这些产品继承自统一父类),每一个具体工厂可产生多种产品.比如,我这里的一个抽象工厂可产生窗口和控件,红色工厂可产生红色的View和Control,绿色工厂可产生绿色的View和Control,但红绿工厂产生的View都继承自IView,Control继承自IControl。

    public abstract class AbstractFactory
    {
        public abstract IView CreateView();
        public abstract IControl CreateControl();
    }

以具体绿工厂为例:

    public class GreenFactory : AbstractFactory
    {
        public override IView CreateView()
        {
            return new GreenView();
        }
        public override IControl CreateControl()
        {
            return new GreenControl();
        }
    }
    public class GreenView : IView
    {
        public void Display()
        {
            System.Console.WriteLine("绿色窗口");
        }
    }
    public class GreenControl : IControl
    {
        public void Display()
        {
            System.Console.WriteLine("我是 绿色工厂 生产出来的 绿色 控件。");
        }
    }

红色工厂类似我就不再贴出代码了,直接看一下调用:

    class Program
    {
        static void Main(string[] args)
        {
            AbstractFactory.AbstractFactory factoryG = new GreenFactory();
            IView viewG = factoryG.CreateView();
            viewG.Display();
            IControl controlG = factoryG.CreateControl();
            controlG.Display();

            System.Console.WriteLine();

            AbstractFactory.AbstractFactory factoryR = new RedFactory();
            IView viewR = factoryR.CreateView();
            viewR.Display();
            IControl controlR = factoryR.CreateControl();
            controlR.Display();

            System.Console.ReadLine();
        }
    }


运行结果:

 

简单工厂&工厂方法对比:

简单工厂 工厂方法 抽象工厂 
所有实例化在同一个类中实现,将对象封装 创建一个接口,让子类决定如何实现  
对象被封装,违背开闭原则,弹性弱 将实例化延迟到子类 易膨胀,过于臃肿


参考链接:http://www.cnblogs.com/BoyXiao/archive/2010/05/06/1728808.html

原文地址:https://www.cnblogs.com/YunGy/p/5067202.html