建造者模式

模板方法模式VS建造者模式

分类: 设计模式 222人阅读 评论(0) 收藏 举报


今天再来两个设计模式的对决,模板方法模式VS建造者模式。

首先,看看模板方法模式的定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。它的UML图如下:


AbstractClass是抽象类,其实也就是一个抽象模板,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类ConcreteClass中实现。

模板方法模式的主要特点是什么呢?

模板方法模式是通过把不变行为搬移到父类(超类),去除了类中的重复代码来体现它的优势。模板方法模式就是提供了一个代码复用的平台。当遇到一系列步骤构成的过程需要执行,这个过程从高层次上看是相同的,但有些步骤的实现可能不同时就可以考虑使用模板方法模式。也就是说,当不变和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。能过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

以下是本人的一个小小的例子的代码:
#include <iostream>

using namespace std;

class Abstract2
{
public:
virtual ~Abstract2(){}
void TemplateMethod()
{
__MethodA();
__MethodB();
__MethodC();
}
private:
void __MethodA(){cout<<"1、选’"<<_AnswerA()<<"’"<<endl;}
void __MethodB(){cout<<"2、选’"<<_AnswerB()<<"’"<<endl;}
void __MethodC(){cout<<"3、选’"<<_AnswerC()<<"’"<<endl;}
protected:
Abstract2(){}
virtual string _AnswerA()=0;
virtual string _AnswerB()=0;
   virtual string _AnswerC()=0;
};

class ConcreteA2:public Abstract2
{
protected:
virtual string _AnswerA()
{
return "A";
}
virtual string _AnswerB()
{
return "B";
}
virtual string _AnswerC()
{
return "C"; 
}
};

class ConcreteB2:public Abstract2
{
protected:
virtual string _AnswerA()
{
return "B";
}
virtual string _AnswerB()
{
return "B";
}
virtual string _AnswerC()
{
return "A"; 
}
};
int main()
{
Abstract2 *pA(new ConcreteA2);
pA->TemplateMethod();
delete pA;
pA = new ConcreteB2;
pA->TemplateMethod();
system("pause");
return 0;
}

再来看看建造者模式,它的定义为:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它的UML图如下:


Builder是为创建一个Product对象的各个部件指定的抽象接口,ConcreteBuilder是具体建造者,实现Builder接口,构造和装配各个部件。Director是指挥者,它是构建一个控制建造过程,也用它来隔离用户与建造过程的关联。

那么它又有什么特点呢?
建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它可以使用户只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以基需要改变一个产品的内部表示,只需要再定义一个具体的指挥者就可以。它主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

以下是本人写的一个小小的例子:

#include <iostream>

using namespace std;

class Automobile//抽象汽车类
{
public:
virtual ~Automobile(){cout<<"destruction automobile"<<endl;}
virtual void BuildWheel()=0;        //建造车轮
virtual void BuildBody()=0;        //建造车身
virtual void BuildVehicle()=0;    //建造车壳
protected:
Automobile(){}
};

class Car:public Automobile
{
public:
virtual void BuildWheel()
{
cout<<"build the wheel of car"<<endl;
}
virtual void BuildBody()
{
cout<<"build the body of car"<<endl;
}
virtual void BuildVehicle()
{
cout<<"build the Vechicle of car"<<endl;
}
~Car(){cout<<"destruction car"<<endl;}
};

class Truck:public Automobile
{
public:
virtual void BuildWheel()
{
cout<<"build the wheel of Truck"<<endl;
}
virtual void BuildBody()
{
cout<<"build the body of Truck"<<endl;
}
virtual void BuildVehicle()
{
cout<<"build the Vechicle of Truck"<<endl;
}
~Truck(){cout<<"destruction truck"<<endl;}
};

class Director    //指挥者类,指挥车的生产过程
{
public:
Director(Automobile *p):pAm(p){}
void Build()
{
pAm->BuildBody();
pAm->BuildWheel();
pAm->BuildVehicle(); 
}
private:
Automobile *pAm;
};

int main()
{
Truck *pTk(new Truck);
Director D(pTk);
D.Build();
delete pTk;
system("pause");
return 0;
}

咋看之下,可能会觉得这两个模式之间没什么是相同的,那它们都有什么不同和相同之处呢?

以下是本人的一些看法,初学设计模式,如有不正确,还望指出。

首先,模板方法模式是行为型模式,而建造者模式是创建型模式。

行为型模式设计到算法和对象间的职责分配,不仅描述对象或类的模式,还描述它们之间的通信方式,刻划了运行时难以跟踪的复杂的控制流,它们将你的注意力从控制流转移到对象间的关系上来。行为型类模式采用继承机制在类间分派行为,例如Template Method 和Interpreter;行为对象模式使用对象复合而不是继承。一些行为对象模式描述了一组相互对等的对象如何相互协作以完成其中任何一个对象都单独无法完成的任务,如Mediator、Chain of Responsibility、Strategy;其它的行为对象模式常将行为封装封装在一个对象中,并将请求指派给它。

创建型模式抽象了实例化过程。他们帮助一个系统独立于如何创建、组合和表示他的那些对象。一个类创建型模式使用继承改变被实例化的类。而一个对象创建型模式将实例化委托给另一个对象。

也就是说,模板方法模式是用来控件对象和类的通信等的,而建造者模式是用来创建对象的。

那么它们真的没有一点联系吗?个人认为不是。

我认为,建造者模式同样体现着模板方法,因为Builder类中定义好了ConcreteBuilder必须要重写或要有的方法也就是说Builder中已定义好了要有的方法,这些方法可以在Builder类中实现,也可以把它推迟到子类中实现。用回以上的两个例子,模板方法中Abstract2类 的重要函数TemplateMethod与建造者模式中的Director类中的函数Build相似,都是定义了方法的执行的骨架。那么撇开模板方法模式是行为型模式,而建造者模式是创建型模式来谈,它们究竟还有什么不同呢?我认为,在实现方法的骨架层次上,建造者模式中使用的是组合的方式,而模板方法模式采用的是继承的方式,我们都知道,组合优于继承,所以我认为建造者更灵活,而且也可以避免由继承而引发的各种问题,如代码膨涨,责任过大,难以维护等。

ps: 个人认为,指挥者类是建造模式的核心和灵魂所在,若没有指挥者类,则建造者模式可退化为一个模式方法模式,详情可见本人另一篇博文:建造者模式中指挥者类的作用,http://blog.csdn.net/ljianhui/article/details/8280594;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值