设计模式【三】:工厂方法
伪代码
class Creator{
public:
virtual Product* Create(ProductId id){
if(id == MINE) return new MyProduct;
if(id == YOURS) return new YourProduct;
return 0;
}
}
// 现在若“你我”转换,需要一个新的creator
class MyCreator: public Creator{
public:
Porduct* Create(ProductId id){
if(id == YOURS) return new MyProduct;
if(id == MINE) return new YourProduct;
if(id == THEIRS) return new TheirPodcut;
return Creator::Create(id);//如果有其他情况,转交给父类方法处理
}
}
优缺点
优点
- 首先,工厂方法又名虚构造器。这不是优缺点,但有助于对此设计模式的理解。
- 为子类提供可扩展产品类的切入点。
缺点
- 工厂方法的滥用可能导致仅仅是为了得到一个新的产品就需要重新继承一次。如伪代码所示:伪代码仅为工厂方法的核心示例,但若应用中如伪代码所示仅仅是生产简单的产品类,一整个类中只有这一个方法,则需要权衡。
何时使用
假如一个父类C需要一个函数创造产品P。C,P均为抽象类,父类C只知晓何时应当创造P,但具体为P的何种子类,是P1还是P2,还是日后更新可能引入的某种当前未知的P3,这是C所不知晓的。此时C可采用工厂方法,将具体P的类别的决定权交给子类处理。
实现时技巧
- 一般情况下,实现结构有两种:
- 构造类是抽象类,工厂方法是虚函数,每一个构造类的子类都需要对工厂方法重写。
- 构造了是实体类,工厂方法对产品类的构造约定了一种默认的构造方式,子类依据具体情况重写产品类,并在未知情况(比如伪代码中除了MINE, YOURS, THEIRS)下调用父类。
- 可采用模板以避免子类继承。既然我们不知道产品P的具体种类,那我们把它做成模板不就好了。
- 方法命名。在不同的开发手册或命名规范中,一般对于工厂方法的命名有要求。当然,这是方便开发者阅读代码。