Builder模式——设计模式学习

转载 2015年07月10日 10:31:18

Buileder(生成器)—对象创建型模式

一 意图

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

二 适用性

在以下情况使用Build模式:

1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

2 当构造过程必须允许被构造的对象有不同的表示时。

3 Builder模式要解决的也正是这样的问题:

  当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),

  我们要复杂对象的创建过程和这个对象的表示(展示)分离开来,

  这样做的好处就是通过一步步的进行复杂对象的构建,

  由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

  在书中第一个例子RTF文档阅读器的实现中,可以看到文档RTFReader支持。


从此图中可以看到:

1封装了三种复杂对象的构建:

ASCIIText,TeXText,TextWiWdget,分别对应不同的builder

2 同样的创建过程创建不同的表示

    可以在RTFReader中对文档进行解析的时候while循环,对于同样的文档,使用不同builder创建产品,同样过程可以得到不同的表示。

3 复杂对象构建分过程进行

    在while循环中,可以看到对不同类型的文档构件,处理的方式不同。分成不同的部分进行处理。

 

三 结构图

 

四 交互过程


Director:是构造一个使用Builder接口的对象

Client创建Director对象,并用它所想要的Builder对象进行配置。

Director创建和装配对象过程

 

五 代码实现

 1 Product

 

复制代码
/************************************************************************
* Product Controls *
**********************************************************************
*/

/***********************************************
* Class Frame *
*********************************************
*/
class Frame
{
public:
virtual void draw() = 0;
};

/***********************************************
* Class Title *
*********************************************
*/
class Title : public Frame
{
public:
virtual void draw()
{
cout<<"title draw"<<endl;
}
};

class TextTitle: public Title
{
public:
virtual void draw()
{
cout<<"TextTitle draw"<<endl;
}
};

class ImageTitle: public Title
{
public:
virtual void draw()
{
cout<<"ImageTitle draw"<<endl;
}
};

/***********************************************
* Class Menu *
*********************************************
*/
class Menu : public Frame
{
public:
virtual void draw()
{
cout<<"menu draw"<<endl;
}
};

class ListMenu: public Menu
{
public:
virtual void draw()
{
cout<<"ListMenu draw"<<endl;
}
};

class ThreeDMenu: public Menu
{
public:
virtual void draw()
{
cout<<"3DMenu draw"<<endl;
}
};

/***********************************************
* Class Toolbar *
*********************************************
*/
class Toolbar : public Frame
{
public:
virtual void draw()
{
cout<<"Toolbar draw"<<endl;
}
};

class CellToolbar : public Toolbar
{
public:
virtual void draw()
{
cout<<"CellToolbar draw"<<endl;
}
};

class FloatToolbar : public Toolbar
{
public:
virtual void draw()
{
cout<<"FloatToolbar draw"<<endl;
}
};

/***********************************************
* Class Button *
*********************************************
*/
class Button : public Frame
{
public:
virtual void draw()
{
cout<<"Button draw"<<endl;
}
};

class TextButton : public Button
{
public:
virtual void draw()
{
cout<<"TextButton draw"<<endl;
}
};

class ImageButton : public Button
{
public:
virtual void draw()
{
cout<<"CellToolbar draw"<<endl;
}
};

class ThreeDButton : public Button
{
public:
virtual void draw()
{
cout<<"ThreeDButton draw"<<endl;
}
};

/***********************************************
* Class Page *
*********************************************
*/
class Page : public Frame
{
public:
#define FRAME_MAX 10

Page()
{
m_frame_num = 0;
}

void AddFrame(Frame* frm)
{
if (m_frame_num < FRAME_MAX)
{
m_frame[m_frame_num] = frm;
m_frame_num++;
}
}
virtual void draw()
{
cout<<"page draw"<<endl;
for (int i =0; i < m_frame_num; i++)
{
m_frame[i]->draw();
}
}
private:
Frame* m_frame[FRAME_MAX];
int m_frame_num;
};

class SlidePage : public Page
{
public:
virtual void draw()
{
Page::draw();
cout<<"SlidePage draw"<<endl;
}
};

class VaryPage : public Page
{
public:
virtual void draw()
{
Page::draw();
cout<<"VaryPage draw"<<endl;
}
};
复制代码

 

2 Builder

复制代码
/************************************************************************
* Build ControlBuilder *
**********************************************************************
*/

/***********************************************
* Class ControlBuilder *
*********************************************
*/
class ControlBuilder
{
protected:
ControlBuilder(){}
public:
virtual void BuildTitle() { }
virtual void BuildMenu() { }
virtual void BuildToolbar() { }
virtual void BuildButton() { }
virtual void BuildPage() { }

virtual Page* GetPage() {return NULL;}
};

/***********************************************
* Class GenerralControlBuilder *
*********************************************
*/
class GenerralControlBuilder: public ControlBuilder
{
public:
virtual void BuildTitle()
{
Title* tl = new TextTitle();
m_page->AddFrame(tl);
}
virtual void BuildMenu()
{
Menu* mu = new ListMenu();
m_page->AddFrame(mu);
}
virtual void BuildToolbar()
{
Toolbar* tb = new CellToolbar();
m_page->AddFrame(tb);
}
virtual void BuildPage()
{
m_page = new SlidePage();
}

virtual Page* GetPage()
{
return m_page;
}
private:
Page* m_page;
};

/***********************************************
* Class MagicControlBuilder *
*********************************************
*/
class MagicControlBuilder: public ControlBuilder
{
public:
MagicControlBuilder()
{
m_page = NULL;
}

virtual void BuildTitle()
{
Title* tl = new ImageTitle();
m_page->AddFrame(tl);
}
virtual void BuildMenu()
{
Menu* mu = new ThreeDMenu();
m_page->AddFrame(mu);
}
virtual void BuildToolbar()
{
Toolbar* tb = new FloatToolbar();
m_page->AddFrame(tb);
}
virtual void BuildButton()
{
Button* btn = new ThreeDButton();
m_page->AddFrame(btn);
}
virtual void BuildPage()
{
m_page = new VaryPage();
}

virtual Page* GetPage()
{
return m_page;
}
private:
Page* m_page;
};
复制代码


3 Director

复制代码
/************************************************************************
* Director PageDirector *
**********************************************************************
*/

/***********************************************
* Class PageDirector *
*********************************************
*/
class PageDirector
{
public:
PageDirector(ControlBuilder* builder)
{
m_builder = builder;
}
virtual Page* CreatePage()
{
m_builder->BuildPage();
m_builder->BuildTitle();
m_builder->BuildMenu();
m_builder->BuildToolbar();
m_builder->BuildButton();

return m_builder->GetPage();
}
private:
ControlBuilder* m_builder;
};
复制代码


4 Client

复制代码
/************************************************************************
* Client *
**********************************************************************
*/
bool ShowPage(Page* pg)
{
pg->draw();

return true;
}

int main()
{
MagicControlBuilder* mgcCtrl = new MagicControlBuilder();

PageDirector* drctr = new PageDirector(mgcCtrl);
drctr->CreatePage();

Page* pg = mgcCtrl->GetPage();

ShowPage(pg);

return 0;
}
复制代码


《形似神不似》


六 实例分析

 

 

在这个例子中:VcpTextView支持以下几种显示方式:

UnicodeText,RichText,IconObject,CoustomObject。

每一种之间都是独立不可替换的,相对具有比较复杂的算法。

在显示的时候使用VcpTextBasicLayout来导向装配显示各元素。

但是在大多数实际应用中很多情况,不可能完全的找出书中所描述的情形,

大多数只是在某一部分是符合Builder模式。

 

七 分析总结

效果:

1 隐藏产品的内部表示

  Builder提供创建产品的接口给Director,

  隐藏了产品的内部结构(仅提供接口BuildPart()创建产品)

  隐藏该产品是如何装配的(BuildPart()内部装配是隐藏的)。

2 将构造代码和表示代码分开

  构造代码是在Builder提供的接口中完成的,每个ConcreateBuilder包含了创建和装配一个特定产品的所有代码。

  提供不同的Builder,使用相同的Director导向过程可以得到不同的表示。

  使用的不同Client可以使用相同的Builder,得到不同相同的表示。


在前面RTFReader阅读器的例子中:

  如果提供ASCIIText Converter 则只能得到ASCIIText,提供TexText Converter则可以得到TexText。

  如果使用XMLReader,提供ASCIIText Converter 使用Director得到不同于的ASCIIText的表示。

  所以将构造代码和表示代码分开,可以使代码得到重用。

3 精确的控制导向产品的创建

  将代码的构建过程委托为Director去完成,那么Client可以不用关注产品的构建过程

  何时完成或者完成到什么程度,交给Director去控制产品的创建和装配的过程。并返回所创建的产品,或者通知Client。

 

在实际的使用情况中可能都并非如此,大多数只能在某些部分匹配Builder模式。


推荐一篇关于Builder模式文章阐述的不错:

http://www.cnblogs.com/happyhippy/archive/2010/09/01/1814287.html



本文出处:http://www.cnblogs.com/bastard/archive/2011/11/21/2257625.html

设计模式学习之Builder模式

建造者模式(Builder Pattern),是创造性模式之一,Builder 模式的目的则是为了将对象的构建与展示分离。Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道...
  • hjxgood
  • hjxgood
  • 2017年04月21日 15:09
  • 512

【java设计模式】之 建造者(Builder)模式

我们还是举上一节的例子:生产汽车。上一节我们通过模板方法模式控制汽车跑起来的动作,那么需求是无止境的,现在如果老板又增加了额外的需求:汽车启动、停止、鸣笛引擎声都由客户自己控制,他想要什么顺序就什么顺...
  • eson_15
  • eson_15
  • 2016年05月06日 08:59
  • 5074

设计模式之四 --- 建造(Builder)模式

【1】基本概念            建造(Builder)模式是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象...
  • cjjky
  • cjjky
  • 2012年03月07日 01:01
  • 16996

builder设计模式的使用以及优缺点

嗯,大家是否在开发过程中,经常遇到一个类拥有许多的属性呢。为了使这个类的使用便捷,我们通常情况下会给这个类多个构造器以及一个默认的无参数构造器。 但是当参数的个数达到四个或者更多的时候,你是否会经常...
  • u010469003
  • u010469003
  • 2014年04月03日 15:16
  • 1830

Android开发中无处不在的设计模式——Builder模式

上一篇文章介绍了单例模式,这一篇继续介绍一个常见的模式——Builder模式。那么什么是Builder模式呢。你通过搜索,会发现大部分晚上的定义都是 将一个复杂对象的构建与它的表示分离,使得同样的...
  • sbsujjbcy
  • sbsujjbcy
  • 2015年10月18日 10:16
  • 5099

Android设计模式之建造者模式(builder pattern)

builder设计模式我们很常见,比如我们使用AlertDialog的时候就使用的builder设计模式,著名的Universal-Image-Loader的初始化配置也是使用的builder设计模式...
  • nugongahou110
  • nugongahou110
  • 2015年12月25日 10:08
  • 2954

浅谈JAVA设计模式之——建造者模式(Builder)

一、概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 二、适用性 1.当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。 2.当构造过程必须允许被...
  • l1028386804
  • l1028386804
  • 2015年05月02日 21:22
  • 9816

PHP设计模式之Builder模式

Builder模式让我想到一个词“外包”,他把对象的创建外包给一个客户类,并且这个“外包类”要一步一步地创建对象,但是他又不返回本身类的对象。当然,这只是个比方,不是很准确,其实Builder模式要解...
  • hcb0825
  • hcb0825
  • 2011年04月15日 17:05
  • 877

java中Builder设计模式 原理和好处

Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成。那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Builder模式来替代...
  • qq_23901559
  • qq_23901559
  • 2015年10月23日 23:20
  • 1603

Java设计模式——Builder模式

builder模式的使用目的是为了将构建复杂对象的过程和它的部件解耦。将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。...
  • u013761665
  • u013761665
  • 2015年12月11日 13:47
  • 2721
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Builder模式——设计模式学习
举报原因:
原因补充:

(最多只允许输入30个字)