对设计模式的个人见解和认识-----工厂方法模式
今天看了一下设计模式中的工厂方法模式,下面这句话是博客园的牛人李会军在.net设计模式中对工厂方法模式的概述:在软件系统 中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供 一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。
从上述描述中,我个人认为Factory Method模式适用的场景具备三个特点:1、某个对象需要经常创建;2、由于需求经常变化,所以这个对象的具体实现也是经常变化;3、虽然该对象经常变化,但是该对象有比较稳定的接口,我对这种接口理解为固定的行为属性。
所以在文章中以记录日志为例来讲解工厂方法的具体实现中作者首先对日志对象(上文中提到的经常面临变化的对象)做了抽象:
public abstract class Log { public abstract void WriteLog();//////所谓的该类对象中比较稳定的接口 }
当具体需要EventLog对象的时候,我们直接定义一个继承自类Log的具体的类:
public class EventLog:Log { public void WriteLog() { Console.Write("EventLog!"); } }
当具体需要FileLog对象的时候,同样创建一个继承自Log的类即可,如下:
public class FileLog { public void WriteLog() { Console.Write("FileLog!"); } }
以上实现我们已经满足了上文中所述的场景中的三个特点中的2、3特点,那么我们还得对第一个特点进行处理,
即:该对象是要经常被创建的,那么我们就需要产生一个用于创建Log具体对象的类,如果需要EventLog那么就产生一个专门用于创建EventLog对象的类,如下:
public class EventLogFactory { public EventLog CreateLogObj() { return new EventLog(); } }
如果需要FileLog对象,那么就产生一个用于创建FileLog对象的类,如下:
public class FileLogFactory { public FileLog CreateLog() { return new FileLog(); } }
以此类推,如果我们还需要其他的Log对象就意味着我们还需要产生其他的用于创建具体Log对象的工厂类,这样虽然可以,但是代码量非常大,而且当需求变化时,我们得产生新的用于创建具体Log对象的工厂类,同时客户端也得修改代码,有违软件设计的开闭原则,所以我们需要将创建具体Log对象的工厂类抽象一下:
public abstract class LogFactory { public abstract Log CreateLog(); }
这样抽象以后,我们要创建具体的Log对象的时候只需要创建一个可以生成具体Log对象的工厂类即可:
public class EventLogFactory:LogFactory { public Log CreateLog() { return new EvengLog(); } }
这样设计的话,我们在客户端需要具体的日志对象去记录日志的话只需要如下代码即可实现
public class ClientApp { public static void Main() { LogFactory factory=new EventLogFactory(); Log log=factory.createLog(); log.Write(); } }