设计模式——工厂方法模式
工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂方法模式在实现是,客户端需要决定实例化哪一个工厂来实现那个产品,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内容的内部逻辑判断移动到了客户端代码类进行,如果想要加功能的话,本类是改工厂类的,而现在是修改客户端。
下面就以书上的雷锋的例子做具体的展示吧。
薛雷峰不能去帮助老人,所以拜托别人去代替他,代替他的人可能大学生,也可能是志愿者,雷锋做的事,大学生和志愿者也要做。所以大学生和志愿者是雷锋的子类。使用工厂方法模式的UML图是这样的:
代码如下:
雷锋类:雷锋类具有扫地、洗衣、买米等方法
<span style="font-family:KaiTi_GB2312;font-size:24px;">class Leifeng { public void Sweep() { Console.WriteLine("扫地"); } public void Wash() { Console.WriteLine("洗衣"); } public void BuyRice() { Console.WriteLine("买米"); } } </span>学生和志愿者继承雷锋:
<span style="font-family:KaiTi_GB2312;font-size:24px;">class Student:Leifeng //学生继承雷锋类 { } class Volunteer:Leifeng //志愿者继承雷锋 { }</span>
建立雷锋的工厂方法
雷锋接口:
<span style="font-family:KaiTi_GB2312;font-size:24px;">interface IFactory { Leifeng CreatLeiFeng(); } 学生工厂和志愿者工厂分别实现接口: class StudentFactory:IFactory //学生实现雷锋接口 { public Leifeng CreatLeifeng() { return new Student (); } } class VolunteerFactory:IFactory //志愿者实现雷锋接口 { public Leifeng CreatLeifeng() { return new Volunteer(); } } </span>
一切准备就绪,只差客户端的代码了:
客户端:
static void Main(string[] args) { IFactory factory = new StudentFactory(); Leifeng stu = factory.CreatLeiFeng(); stu.BuyRice(); //调用学生的方法 stu.Sweep(); stu.Wash(); }
整个例子到此完成了。
由此可见工厂方法客服了简单工厂违背开发-封闭的缺点,又保持了封装对象创建过程的优点。工厂方法模式是简单工厂方法的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单的工厂模式的优点,而且克服了他的缺点。但缺点是由于每增加一个产品,就需要增加一个产品工厂的类,增加了额外的开发量。