在现实生活中,有很多东西都是作为附属物出现的,如手机套附属于手机,电脑膜附属于电脑,我们很多时候都会把精力集中在主要物中,而忽略这些附属物。面向对象编程能很好的反映现实中实际存在的物件以及关系,factory method设计模式是解决这样的主从关系明显的方法,能帮我们抓住主要重点。
factory method设计模式在UML类图中如下表示
Produce和Creator都是抽象类,Cteator提供创建Produce类的接口,在子类ConcreteCreator中实现,实现的createProduce会产生ConcreteProduce类。
举一个具体一点的例子吧!
假如Produce是一个手机套,我们要为每一个手机生成一个手机套与其搭配,但是我们的重点并不是在手机套上。我可以声明下面的类。
/*class PhoneCover*/
class PhoneCover {
public:
virtual void setColor(int colorType) = 0;
virtual ~PhoneCover();
};
/*class Phone*/
class Phone {
public:
virtual PhoneCover* createPhoneCover() = 0;
virtual ~Phone();
};
/*class ApplePhoneCover*/
class ApplePhoneCover: public PhoneCover{
private:
int m_color;
public:
void setColor(int color) { m_color = color; }
};
/*class ApplePhone*/
class ApplePhone: public Phone{
public:
PhoneCover* createPhoneCover() { return new ApplePhoneCOver; }
};
对上述类,我们可以创建ApplePhone的手机对象,如果我们关心手机的手机套,我们调用手机对象的createPhoneCover函数即可创建ApplePhoneCover手机套对象,我们可以为其设定颜色。就这么简单。
也许这还没有反映出factory method的优势,试想一下,如果我们现在有一种新的类型手机,怎么去处理呢?可以如下解决:
/*class HTCPhoneCover*/
class HTCPhoneCover: public PhoneCover{
private:
int m_length;
int m_width;
int m_color;
public:
HTCPhoneCover(int length, int width): m_length(length), m_width(width) {}
void setColor(int color) { m_color = color; }
};
/*class HTCPhone*/
class HTCPhone: public Phone{
priavte:
int m_length;
int m_width;
public:
PhoneCover* createPhoneCover() { return new HTCPhoneCover(m_length, m_width); }
};
这样,我们就将手机套和手机绑定在一起了,我们的用户在创建了手机之后,不至于要花时间去思索应该创建哪个手机套类,减少了用户放错的机会。
factory method还有另一种实现方法。
大家应该对动物饼干比较熟悉吧,下面就以它为例
/*class Biscuit*/
class Biscuit{
public:
...
virtual ~Biscuit();
};
/*class DogBiscuit*/
class DogBiscuit: public Biscuit{
public:
...
};
/*class CatBiscuit*/
class CatBiscuit: public Biscuit{
public:
...
};
enum BiscuitType{
dog,
cat,
...
};
Biscuit* createBiscuit(int type)
{
switch(type) {
case dog:
return new DogBiscuit;
case cat:
return new CatBiscuit;
...
}
}
这样,就可以根据不同参数,函数创建不同的饼干。