当前位置:首页 > 芯闻号 > 充电吧
[导读]一 意图将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。二 适用性在以下情况使用Build模式:1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。2 当

一 意图

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

二 适用性

在以下情况使用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模式。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭