本文使用C++来介绍工厂方法模式。
小新接到客户需求,需要建造一个房间,该房间非常简单,由门、窗和墙组成。客户对于门、窗和墙有多种需求,比如木门、隔音窗、绿墙等等。
除去前面文章中提到的抽象工厂模式和生成器模式,小新开始从细节思考客户的需求,决定从门这一个单一产品入手。客户的需求是多样的,小新假定客户需要木门和铁门两种产品。
由前面的经验可知,要隐藏相关产品的实现细节,简化客户的操作,我们需要工厂来产生相应的产品,这里的产品是指门,工厂是指门的生产类。
首先对于产品门,我们可以创造一个门类,并由其派生出木门和铁门两个子类。
class Door {
public:
Door() { }
}
class WoodDoor : public Door {
public:
WoodDoor() { cout << "木门"; }
}
class IronDoor : public Door {
public:
IronDoor() { cout << "铁门"; }
}
然后对于工厂,我们可以创造一个工厂类,并由其派生出木门工厂和铁门工厂两个子类。
class DoorFactory {
public:
virtual Door* CreateDoor() = 0;
}
class WoodDoorFactory : public DoorFactory {
public:
WoodDoor* CreateDoor() { return new WoodDoor; }
}
class IronDoorFactory : public DoorFactory {
public:
IronDoor* CreateDoor() { return new IronDoor; }
}
其中CreateDoor即体现出工厂方法模式。回到客户的需求,客户在需要门之前并不知道是应该创建木门还是铁门,小新使用门的子类来指定客户需要创建的对象。在上面的例子中,木门和铁门处于同一产品层次,木门工厂和铁门工厂处于同一工厂层次,同一层级的工厂对应着同一层级的一个产品。客户可以使用如下方式得到木门和铁门。
WoodDoorFactory woodDoorFactory;
WoodDoor *woodDoor = woodDoorFactory.CreateDoor();
IronDoorFactory ironDoorFactory;
IronDoor *ironDoor = IronDoorFactory.CreateDoor();
工厂方法模式适用于如下情况(参考自(设计模式))
1、当一个类不知道它所必须创建的对象的类的时候。
2、当一个类希望由它的子类来指定它所创建的对象的时候。
3、当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。(对于后一句,个人理解意思应该是在局部区域,你希望使用某一个子类来生成产品。如有错误,感谢大家指正。)
工厂方法的缺点很明显,客户每次要创建一个特定的门对象,就不得不创建一个DoorFactory子类。当该产品的特定种类增多,或者增加窗、墙等新产品时,不断增加的子类会显得非常繁琐。
从上面的介绍可以看出,工厂方法模式和抽象工厂模式有很大的联系,实际上,抽象工厂模式经常使用工厂方法来实现。下一节我们将介绍工厂方法模式和抽象工厂模式的区别。