如果说 Factory和Prototype是同一个层次的话,那么Abstract Factory和Builder就是更高一级的层次。
很多人都对这两个设计模式的区别不是很清楚,包括我也一样,所以今天特地在这里列举一下他们之间的异同点,来做个比较。(以下简称前者为A,后者为B)
一、意图的比较
A:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
B:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
从上述可以看出,两者同为对象创建型设计模式,但是前者是为了设计一个互相协作的对象组,而后者则侧重于创建一个复杂对象。也就是说虽然两者都提供了一系列类的接口用来返回一个产品,但前者是因为构成产品的对象组相关联才看起来像一个复杂对象,后者才真正是由一个复杂对象构成的产品。也可以理解为前者是产品集,后者是零件集。
二、重要的效果比较
A:它使得易于交换产品系列。
B:它使你可以改变一个产品的内部表示。
从上面两个效果可以得出相同的结论,A的效果还是为了让一个产品集发生作用,而这个产品集合你可以把他们写成对象,也可以不写,因为他们是相互关联的,因此当你改变了产品中的任何一个,必然导致产品系列的变更。而后者不一样,他是由一些不需要相关联的类构成的复杂对象,你不知道那些类是怎么实现,但你可以通过B提供的接口根据你的需要完成产品的装配且不会改变这个产品的根本性质,所以效果中有可以改变一个产品内部表示这样一条。
三、例子&总结
所以我觉得,使用A还是使用B,应该具体放到你想解决什么问题上,比如你想构造一所房子,如果你把构建的侧重点放在房子的完整性上,那么你必然要选择A,因为你需要构成房子所需要的所有产品,比如门,窗等,如果没有这些,房子就不称为房子了(注意我们关心的是房子的完整性),而房子的完整性则需要所有的产品集协作才能体现,所以产品集合必须一次性创建才有意义。但如果你把构建的侧重点放在房子的外观上,那么你应该选择B,你可以只选择造没有门的房子,也可以造没有窗户的房子,但是就算如此,房子依然是个房子,因为你并没有关心房子是不是需要全部的零件(如窗),所以你不需要一次性返回产品,因为这个对象已经存在了(你要做的是改变它的部分),而是等待你的一步一步的装配。
所以我觉得,是使用A还是使用B,应该看是关心一个产品集的协作,还是关心构建复杂一个对象。当然,这仅仅是我一家之言,希望大家多提意见,谢谢。
1 Abstact Factory
在上面的Factory类型中,我们发现如果种类变了,我们还是要修改我们的代码: Factory = new 宝马工厂。 这样的代码可能出现在很多的地方,改起来并不是很方面。那么怎么办呢? 我们能不能把修改集中在一个地方?答案是可以的,那就是Abstract Factory。我们专门生成一个类来管理工厂,把 Factory = new 宝马工厂 这句话放到他的入口里面。
class AbstractFactory
{
protected:
AbstractFactory():_instance(0){}
public:
virtual Factory* CreateCarFactory()
{
if(0 == _instance)
{
_instance = new 宝马工厂。
}
return _instance;
}
private:
Factory* _instance;
}
上面的代码实现了一个简单的singleton的Abstract Factory。这样,如果下次用户需要一个新的工厂,那么可以从这个AbstractFactory里面派生一个新的类,或者修改代码等等。
这时候,有人要问了,这种操作我们直接用Factory也可以实现阿,直接把原来 宝马工厂 的实现修改不就行了么? 当然可以,但是Abstract Factory的存在价值是 他可以支持更复杂的创建。比如一个军工厂,他生产轿车,飞机,坦克等等。其中的轿车就是我们上面说的轿车,也有很多自己的。我们就可以为军工厂实现一个自己的Abstract Factory.
class AbstractFactory
{
public:
virtual CarFactory* CreateCarFactory();
virtual TankFactory* CreateTankFactory();
virtual PlaneFactory* CreatePlaneFactory();
}
可以看出,一个Abstract Factory的价值在于它可以创建更多的工厂类。当然,他也可以创建具体的实例,prototype类,等等,甚至可以创建一个新的子AbstractFactory。 所以Abstract Factory类似一个总的管理者,管理的是各个实例的工厂。正因为如此,一个程序里面的Abstract Factory往往是singleton的。
2. builder
builder 也是一个高层建筑,但是他和Abstract Factory侧重点不同,Abstract Factory侧重于创建东西的结果,而builder侧重的是创建东西的过程。
class CarBuilder
{
public:
virtual void Setwheel();
virtual void SetMoto();
virtual void SetSeat();
virtual Car* GetCar();
}
在调用的时候采用
Car* CreateCar(CarBuilder& cb)
{
cb.SetWheel(轮子);
cb.SetMoto(马达);
cb.SetSeat(作为);
return cb.GetCar();
}
上面的例子可以看出builder的特征。