• [设计模式]第二回:工厂方法模式(Factory Method)


    1.引言

    在软件系统 中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供 一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。   

    2.实战

    结构图:

    意图:定义一个用户创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

       class Program
        {
    
            static void Main(string[] args)
            {
                LogFactory factory = new EventFactory();
                Log log = factory.Create();
                log.Write();
            }
        }
        public abstract class Log
        {
            public abstract void Write();
        }
        public class EventLog : Log
        {
            public override void Write()
            {
                Console.WriteLine("EventLog Write Success!");
            }
        }
        public class FileLog : Log
        {
            public override void Write()
            {
                Console.WriteLine("FileLog Write Success!");
            }
        }
        //工厂
        public abstract class LogFactory
        {
            public abstract Log Create();
        }
        public class EventFactory : LogFactory
        {
            public override Log Create()
            {
                return new EventLog();
            }
        }
        public class FileFactory : LogFactory
        {
            public override Log Create()
            {
                return new FileLog();
            }
        }

    Main方法还可以使用反射进行创建

            public static void Main(string[] args)
            {
                string strfactoryName = ConfigurationSettings.AppSettings["factoryName"];
    
                LogFactory factory;
                factory = (LogFactory)Assembly.Load("FactoryMethod").CreateInstance("FactoryMethod." + strfactoryName);
    
                Log log = factory.Create();
                log.Write();
            }

     经典应用

     //方式一:
        public static class LogHelp
        {
            private static Log log;
    
            public static void Init(LogFactory factory)
            {
                log = factory.Create();
            }
    
            public static void Write()
            {
                log.Write();
            }
        }

    这种方式可以只初始化一次,以后可以直接用LogHelp.Write()。一般可以在Application_Start 程序启动时调用Init方法初始化,这也是主流做法。再看另一种,如下

        public static class LogHelp
        {
            public static Log GetLog()
            {
                string strfactoryName = ConfigurationManager.AppSettings["factoryName"];
                LogFactory factory = (LogFactory)Assembly.Load("FactoryMethod").CreateInstance("FactoryMethod." + strfactoryName);
                Log log = factory.Create();
    
                return log;
            }
        }

    调用时,直接用  LogHelp.GetLog().Write(),调用哪一个在配置文件中已配置。该方法,每次需要反射,可以考虑方式一 加个静态变量,进行判断是否需要创建。

    3.小结

    • 看到工厂这两个字,就想到加工厂,如果东西出了问题,就找到源头加工厂,工厂方法类似,也是创建对象用的,隐藏了new初始化的操作,也提供了一个创建对象的源头,出了问题很容易找到。
    • 简单工厂是一个具体工厂然后里面进行业务逻辑判断如Case,if等,如果增加了一个产品,要修改逻辑;而工厂方法是一个抽象工厂,增长产品可以添加一个子工厂,体现了开放封闭原则。
    • 工厂创建的对象一般由客户端决定,变化权可以配置在配置文件中,这本身就体现了控制反转思想。一般客户决定了,整个程序中使用的对象就决定了,如数据库,可以配置ms、也可以配置mysql,一般不会出现两种一起使用,配置的话,即使更换方式也不会重新编译。
    • 工厂方法模式还有一个非常重要的意图,就是延迟始化(Lazy initialization)。如何做?一般是一个对象初始化完毕后就不释放,等到再次用到得就不用再次初始化了,直接从内存过中取就行,上面的应用方式一就是典型的做法。

    查考资料 http://terrylee.cnblogs.com/archive/2006/01/04/310716.html

    作者:Qlin
    出处:http://www.cnblogs.com/qqlin/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    linux设备驱动编写_tasklet机制(转)
    Class create, device create, device create file (转)
    android MTK驱动背光唤醒流程
    sysfs接口函数的建立_DEVICE_ATTR(转)
    Android图形显示之硬件抽象层Gralloc(hal 转)
    misc设备
    Android 呼吸灯流程分析
    Linux输入子系统(转)
    Oracle与MySQL的比较[内容来自网络]
    Oracle数据库分区相干知识点
  • 原文地址:https://www.cnblogs.com/qqlin/p/2852849.html
Copyright © 2020-2023  润新知