我们假设有个穷工厂,只生产汽车产品,假设它只能生产车门和车窗。
如果是简单工厂模式,我们会这么做:
汽车产品 汽车产品实例=汽车工厂.get具体产品(); //具体产品可能是车门或窗,而在汽车工厂的这个静态方法里,我们用面向过程的方法,如switch判断来取得我们到底想得到哪个具体产品。
在简单工厂里,我们用简单工厂类来产生子类对象,但是如果我们现在要增加一个具体产品,那么我们就得修改简单工厂,这就违反了“对扩展开放”原则。
其实我们可以把这个汽车工厂分为N个专门小工厂(专产车门、专产车窗),这样要增加具体产品的时候,只要再添加一个子类(继承父工厂类),然后最终用户可以:
汽车工厂 车门产品=new 车门生产厂();抽象出来就是:
工厂 具体产品=new 具体子工厂(); //用户还是需要知道具体的子工厂类的,但不需知道具体产品类;(这句在理解了Factory Method后再最后看)
这就是工厂方法(Factory Method)。
简单工厂:简单工厂是工厂创造子产品;扩展时改工厂,用户不需要知道具体实现;
工厂方法:工厂方法是工厂的子工厂创造子产品;扩展时只要添加一个子产品工厂,还要改用户实现(因为用户还是需要知道具体的子工厂类以便去new)。
工厂方法使用时:
1个[抽象]产品类,派生N个具体产品类;1个[抽象]工厂类,派生N个具体工厂类;
具体工厂和具体产品一一对应。
最后实例化,抽象工厂有一个方法(被重写)返回具体产品。
附用户实现代码部分(具体执行):
using System;
namespace CarFactoryTest
{
class Program
{
static void Main(string[] args)
{
//声明一个基产品
CarHardware carHardware = null;
//实例一个基工厂
CarFactory carFactory = null;
//多态用法。指向一个子产品类。这句就是“变化”的,其它代码都是“不变”的
carFactory = new CarDoorFactory();
//取得具体产品
carHardware = carFactory.getCarHardware();
//使用产品
carHardware.Play();
}
}
}