在简单工厂模式中提到了其存在的缺陷,简单工厂模式违背了“开放-封闭”原则,一旦添加新的产品就不得不修改工厂类的代码,这样会造成工厂类的实现逻辑过于复杂。工厂方法模式的存在就很好地解决了这一问题。
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。说白了,就是把简单工厂模式中的工厂类抽象成一个接口(依赖倒转原则),这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,定义多个要生产具体类的工厂去实现这个接口。这样,当我们想要增加一个产品时,就不用在工厂类中修改代码,直接添加一个工厂方法去实现这个接口就OK了。看一下工厂方法模式的实现过程。
工厂方法模式的结构图。
工厂方法模式的实现
还是学生去食堂打饭的情景,看看工厂方法模式是怎样实现的。这是有关的事物类的实现代码,不再详解。
class Food //抽象事物类
{
public virtual void GetFood()
{
}
}
class Rice : Food //米饭类
{
public override void GetFood()
{
Console.WriteLine("您选择的主食是米饭!");
}
}
class Noodles : Food //面条类
{
public override void GetFood()
{
Console.WriteLine("您选择的主食是面条!");
}
}
class Buns : Food //馒头类
{
public override void GetFood()
{
Console.WriteLine("您选择的主食是馒头!");
}
}
定义一个接口,声明一个工厂方法,该方法返回一个Food类型的对象。
interface IFactory
{
Food ConcreteFood();
}
定义实现这个接口的工厂类,重定义接口中的工厂方法以返回一个ConcreteProduct实例。
class RiceFactory : IFactory//定义“米饭”工厂
{
public Food ConcreteFood()
{
return new Rice(); //实例化“米饭”类
}
}
class NoodlesFactory : IFactory//定义“面条”工厂
{
public Food ConcreteFood()//实例化“面条”类
{
return new Noodles();
}
}
class BunsFactory : IFactory//定义“馒头”工厂
{
public Food ConcreteFood()
{
return new Buns();//实例化“馒头”类
}
}
客户端实现代码
class Program
{
static void Main(string[] args)
{
IFactory factory = new RiceFactory();
Food food = factory.ConcreteFood();
food.GetFood();
}
}
运行结果
简单工厂模式VS工厂方法模式
相同点:集中了对象的创建,使得要更换对象时,不需要做大的改动就可实现,降低了客户端与产品对象的耦合。
不同点:工厂方法模式很好地解决了添加产品的问题,遵循了“开放-封闭”原则。
工厂方法模式保持了简单工厂模式的优点由克服了它的缺点。不过工厂方法模式的不足是由于每增加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
总结:
工厂方法模式是简单工厂的升华,是对工厂类的进一步抽象,使得工厂类中的实现逻辑变得简单。类比到生活中,抽象工厂类和具体工厂类就像是食堂和厨师,食堂只提供一个做饭的场所,厨师负责具体食品的制作。学生要做的就是通过食堂找到这个厨师,然后购买他的食品就OK了。