• 工厂模式


    现在,如果我想要创建一个界面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

  • 相关阅读:
    多数据源配置
    Oracle创建JOB
    2新建Data Adapter
    注解的CRUD;重点:多对一和一对多处理
    Mybatis分页+使用注解开发!
    继续mybatis配置resultMap;讲解日志部分
    Today has a day off.
    Mybatis其他配置!
    Mybatis优化配置!
    Mybatis的CRUD
  • 原文地址:https://www.cnblogs.com/YunGy/p/5067202.html
Copyright © 2020-2023  润新知