[设计模式]第二回:工厂方法模式(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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/qqlin/p/2852849.html