通过联系实际,我们利用一个学雷锋做好事的例子,来体会工厂方法模式和简单工厂的区别与联系。
1、写一个雷锋类,学生继承于雷锋,通过实例化多个对象去完成洗衣、打扫等方法。
2、但是学生都是短期的,如若我们需要增加一个长时间为老人服务的团体——社区志愿者类,同样继承于雷锋。再写出简单工厂类,运用多态,需要社区志愿者或学生时,客户端直接写出需要的指令,实例化不同的类(学生、志愿者两个类)。
代码如下:
//雷锋类
class LeiFeng
{
public void Wash()
{
Console.WriteLine("洗衣服");
}
public void Clean()
{
Console.WriteLine("扫地");
}
}
//学雷锋的大学生,替雷锋做以上工作。
class Undergraduate:LeiFeng
{ }
//长期的帮助老人的组织:社区志愿者
class Volunteer : LeiFeng
{ }
//简单工厂:
class SimpleFactory
{
public static LeiFengCreateLeiFeng(string type)
{
LeiFeng result = null;
switch (type)
{
case "学雷锋的大学生":
result = newUndergraduate();
break;
case "社区志愿者":
result=new Volunteer ();
break ;
}
return result;
}
}
客户端代码:
//简单工厂模式:
LeiFeng Z =SimpleFactory.CreateLeiFeng("学雷锋的大学生");
Z.Clean();
LeiFeng W =SimpleFactory.CreateLeiFeng("社区志愿者");
W.Wash();
//每实例化一个对象,就需要重复一次简单工厂的代码
问题出现了:
(1)、如果需要实例化多个对象,那么均需要不断增加、重复些实例化代码。
(2)、如果还需要增加一个类,为老人提供别的服务时,则又需要修改再写。
以上均违背了OCP原则(对扩展开放,对修改关闭)。由此引入工厂方法模式。
3、工厂模式,由于学生、社区志愿者均拥有相同的方法帮助老人,故写一个接口(雷锋工厂)。再写出学生、志愿者工厂,客户端便可直接需要学生或者志愿者时,直接将实例化工厂类换成相应的工厂即可。不需要重复写继承实现的代码。
代码如下:
//工厂方法模式
interface IFactory
{
LeiFeng CreateLeiFeng();
}
//学雷锋的大学生工厂:
class UndergraduateFactory:IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Undergraduate();
}
}
//志愿者工厂:
class VolunteerFactory : IFactory
{
public LeiFeng CreateLeiFeng()
{
return new Volunteer();
}
}
客户端代码:
IFactory factory = new UndergraduateFactory();
LeiFeng L=factory .CreateLeiFeng();
L.Wash();
L.Clean();
IFactory fatory = newVolunteerFactory();
LeiFeng V =factory.CreateLeiFeng();
V.Clean();
以上三种方式运行结果均如下:
由此看出,工厂方法模式就是简单工厂的进一步升级,保持了简单工厂优点的同时,克服了其每增加一个功能就需要多写一个相应工厂类,违背OCP的缺点。
分享:
1、虽然通过直接写类继承、简单工厂、工厂方法这三种方式编写出来运行均能达到相同的显示结果,但是就设计思路的精密程度和代码的扩展性、维护性、灵活性而言,三者却不尽相同。横向一比较,便再一次明显的提醒我们:设计的最终目的不仅仅只是实现功能。
2、对于设计模式的学习,动手实践很重要。对理论阐述很容易感觉模糊。此时,一定要通过实践,敲例子来帮助加深理解。
希望以上内容,对您有所帮助。不足之处,请多多指教。