设计模式之建造者(Builder)模式

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以表示不同的表示。

适用性

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 当构造过程必须允许被构造的对象有不同的表示时。

UML图

  • Builder ——为创建一个Product对象的各个部件指定抽象接口。
  • ConcreteBuilder ——实现Builder的接口以构造和装配该产品的各个部件。

    ——定义并明确它所创建的表示。

    ——提供一个检索产品的接口。

  • Director ——构造一个使用Builder接口的对象。
  • Product ——表示被构造的复杂对象。
  • ConcreteBuilder创建该产品的内部表示并定义它的装配过程。

    ——包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

代码示例

  ConcreteBuilder中需要提供构建产品的的各个部件的函数,以及对外获取被创建产品的接口。还是以创建迷宫为例,迷宫产品组件包括迷宫自身、房间、门,这些组件创建函数(BuildPart)需定义为虚函数,以便子类继承实现。在产品各部分创建好了后,需要通过对外的接口GetResult来获取创建的产品,本例GetMaze返回创建的迷宫。

class MazeBuilder{
public:
	virtual void BuildMaze(){}
	virtual void BuildRoom(int Room){}
	virtual void BuildDoor(int roomFrom, int RoomTo){}

	virtual Maze* GetMaze(){return 0;}
protected:
	MazeBuilder();
};

  因为builder中BuildPart和GetResult函数都是虚函数,所以Director并不关心继承Builder的子类实现,Director只需要按部就班的调用Builder的BuildPart函数来创建产品,如下例:

builder.BuildMaze();//创建迷宫

builder.BuildRoom(1);//创建1号房间

builder.BuildRoom(2);//创建2号房间

builder.BuildDoor(1,2);//创建1号房间和2号房间的门

在产品各个部件创建完成后,调用:

build.GetMaze();//获取已创建迷宫

Maze* MazeGame::CreateMaze(MazeBuilder& builder){
	builder.BuildMaze();

	builder.BuildRoom(1);
	builder.BuildRoom(2);
	builder.BuildDoor(1,2);

	return builder.GetMaze();
}
MazeBuilder基类提供实现产品的接口,具体实现还需要子类来实现。这里StandardMazeBuilder继承MazeBuilder并实现了基本功能。
StandardMazeBuilder类声明:
class StandardMazeBuilder:public MazeBuilder{
public:
	StandardMazeBuilder();

	virtual void BuildMaze();
	virtual void BuildRoom(int);
	virtual void BuildDoor(int,int);

	virtual Maze* GetMaze();
private:
	Direction CommonWall(Room *, Room *);
	Maze * _currentMaze;
}

StandardMazeBuilder类实现:

#include "Builder.h"

StandardMazeBuilder::StandardMazeBuilder(){
	_currentMaze = 0;
}

void StandardMazeBuilder::BuildMaze(){
	_currentMaze = new Maze;
}

Maze* StandardMazeBuilder::GetMaze(){
	return _currentMaze;
}

void StandardMazeBuilder::BuildRoom(int n){
	if(!_currentMaze->RoomNo(n)){
		Room* room = new Room(n);
		_currentMaze->AddRoom(room);

		room->SetSide(North, new Wall);
		room->SetSide(South, new Wall);
		room->SetSide(East, new Wall);
		room->SetSide(West, new Wall);
	}
}

void StandardMazeBuilder::BuildDoor(int n1, int n2){
	Room *r1 = _currentMaze->RoomNo(n1);
	Room *r2 = _currentMaze->RoomNo(n2);
	Door *d = new Door(r1,r2);

	r1->SetSide(CommonWall(r1,r2),d);
	r2->SetSide(CommonWall(r2,r1),d);
}

   在实现了Director和Builder后,Client无需关心具体产品的具体实现,只需要新建该Builder类,传递给Director,就能创建出不同的产品了。

#include "Direcotr.h"
#include "StandardMazeBuilder.h"

int Main(){

	Maze *maze;
	MazeGame game;
	StandardMazeBuilder builder;

	game.CreateMaze(builder);
	maze = builder.GetMaze();
	return 0;
}

 

优缺点

优点:

  • 将一个复杂对象的创建过程封装起来。
  • 允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。
  • 向客户隐藏产品内部的实现。
  • 产品的实现可以被替换,因为客户只看到一个抽象的接口。

缺点:

  • 与工厂模式相比,采用生成器创建对象的模式,需要具备更多的领域知识。

参考文献:

GOF《设计模式》

时间: 2024-10-19 23:59:01

设计模式之建造者(Builder)模式的相关文章

Java 实现建造者(Builder)模式

建造者(Builder)模式是创建型模式,创建了一个对外隐藏创建过程的产品,使用组合的方式,由指挥者(Director)来决定建造的流程 public interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); } public class BuilderImpl implements Builder { @Override public void buildPartA() { System.out.p

建造者(Builder)模式

在学习MyBatis的过程中遇到了建造者(Builder)模式,查找了相关资料,在这做下记录加深印象. 参考资料: java设计模式-建造者模式(Builder) 人人都会设计模式---建造者模式--Builder <JAVA与模式>之建造模式 1.什么是建造者模式 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,通俗的说就是:建造者模式就是如何一步步构建一个包含多个组成部件的对象,相同的构建过程可以创建不同的产品. 2.一个组装电脑的示例 小明想组装一个台式电脑,小

Android 建造者(Builder)模式

关于 Builder 模式 详述:http://blog.csdn.net/jjwwmlp456/article/details/39890699 先来张图 看到 Android  中 使用了 Builder 模式的地方还是很多的. 使用时 大概如下: Notification noti = new Notification.Builder(context).build(); AlertDialog dialog = new AlertDialog.Builder(context).create

设计模式--建造者(Builder)模式

将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示                                                         --<设计模式>GOF Insus.NET在ASP.NET环境中,列举一个建造者设计模式(Builder)例子,以最帖近开发环境与需求. 开发站点时,我们需要开发新闻类,视频类,图片类等等.每个网页还有可能是页头,内容,页脚等.开发这些页头,内容与页脚时,我们会使用用户控件来写好,加载至网页中去. 每个类别的网页,

Builder模式(建造者模式)

在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代多参数构造函数是一个比较好的实践法则. 我们常常会面临编写一个这样的实现类(假设类名叫DoDoContact),这个类拥有多个构造函数, DoDoContact(String name); DoDoContact(String name, int age); DoDoContact(S

【我的设计模式】建造者模式

建造者(Builder)模式的定义是:将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 首先它意图是要构建一个复杂的对像,而这个复杂的对像往往需要由好几个子对像或分步聚来完成最终的这个对象的构建,而这个复杂对象的子对像经常需要不断的变化,但它的构建过程是相对是稳定的. 应用场景 一部汽车由发动机,轮胎.底盘,车身组成.无论最终构建的汽车是大众牌的汽车还是奥迪汽车,它的构建过程是不会变的,都是由发动机,轮胎.底盘,车身组成.至于大众牌的汽车还是奥迪汽车它们各自采用的是什么

[转]Builder模式在Java中的应用

转自:http://www.cnblogs.com/moonz-wu/archive/2011/01/11/1932473.html 在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代多参数构造函数是一个比较好的实践法则. 我们常常会面临编写一个这样的实现类(假设类名叫DoDoContact),这个类拥有多个构造函数, DoDoCon

Builder模式在Java中的应用(转)

在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代多参数构造函数是一个比较好的实践法则. 我们常常会面临编写一个这样的实现类(假设类名叫DoDoContact),这个类拥有多个构造函数, DoDoContact(String name); DoDoContact(String name, int age); DoDoContact(S

Builder模式在Java中的应用

在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代多参数构造函数是一个比较好的实践法则. 我们常常会面临编写一个这样的实现类(假设类名叫DoDoContact),这个类拥有多个构造函数, DoDoContact(String name); DoDoContact(String name, int age); DoDoContact(S