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