C++实现Creational - Builder模式

在软件系统中,有时候面临着一个复杂对象的创建工作,该复杂对象通常由各个部分的子对象用一定的算法构成。由于需求的变化,这个复杂对象的各个子对象经常面临着剧烈的变化,但是将这些子对象组合在一起的算法是相对稳定的。

 

举例:

假定一个可以放在桌子的相框有两部分组成,即一个框和一个支撑,而且这个组成是不变的。但是有不同风格的框和不同风格的支撑。Builder模式就是用来处理像相框这样复杂的对象的构建的。

 

Builder设计模式,提供一种封装机制来隔离出构成复杂对象的各个子对象的变化,从而保持系统中的相对稳定的将这些子对象组合在一起的算法不随着需求的改变而改变。

 

Separate the construction of a complex object from its representation so that the same construction process can create different representations.  - GoF

 

Builder设计模式中的角色:

建造者(Builder):

给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

 

具体建造者(Concrete Builder):

担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:

- 实现Builder角色提供的接口,一步一步完成创建产品实例的过程。

- 在建造过程完成后,提供产品的实例。

 

指导者(Director):

担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

 

产品(Product):

产品便是需要建造的复杂对象。

 

BuilderUML类图如下:

 

指导者角色是与客户端打交道的角色。指导者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

 

C++实现Builder模式的代码:

// Builder.h

#include <iostream>

#include <string>

#include <memory>

using namespace std;

 

// Parts

// 抽象类Frame,用来规范框的接口

class Frame

{

protected:

         string frame_name;

public:

         virtual string get_frame_name() const= 0;

 

public:

         Frame(const string& frame_name) : frame_name(frame_name)

         {

         }

 

         virtual ~Frame()

         {

                   cout << "in the destructor of Frame..." << endl;

         }

};

 

// 木质框架

class WoodenFrame : public Frame

{

public:

         WoodenFrame() : Frame("木质框")

         {

         }

 

         string get_frame_name() const

         {

                   return frame_name;

         }

 

         ~WoodenFrame()

         {

                   cout << "in the destructor of WoodenFrame..." << endl;

         }

};

 

// 钢质框架

class SteelFrame : public Frame

{

public:

         SteelFrame() : Frame("钢质框")

         {

         }

 

         string get_frame_name() const

         {

                   return frame_name;

         }

 

         ~SteelFrame()

         {

                   cout << "in the destructor of SteelFrame..." << endl;

         }

};

 

// 抽象类Stand,用来规范支撑接口

class Stand

{

protected:

         string stand_name;

public:

         virtual string get_stand_name() const = 0;

 

public:

         Stand(const string& stand_name) : stand_name(stand_name)

         {

         }

 

         virtual ~Stand()

         {

                   cout << "in the destructor of Stand..." << endl;

         }

};

 

// 木质支撑

class WoodenStand : public Stand

{

public:

         WoodenStand() : Stand("木质支撑")

         {

         }

 

         string get_stand_name() const

         {

                   return stand_name;

         }

 

         ~WoodenStand()

         {

                   cout << "in the destructor of WoodenStand..." << endl;

         }

};

 

// 钢质支撑

class SteelStand : public Stand

{

public:

         SteelStand() : Stand("钢质支撑")

         {

         }

 

         string get_stand_name() const

         {

                   return stand_name;

         }

 

         ~SteelStand()

         {

                   cout << "in the destructor of SteelStand..." << endl;

         }

};

 

// Products

// 抽象类Framework,用来规范相框的接口。相框包括框架和支撑,这具体体现为Framework类中的

// 两个protected的成员:framestand

class Framework

{

protected:

         auto_ptr<Frame> frame;

         auto_ptr<Stand> stand;

public:

         virtual void set_frame(auto_ptr<Frame> frame) = 0;

         virtual auto_ptr<Frame> get_frame() = 0;

         virtual void set_stand(auto_ptr<Stand> stand) = 0;

         virtual auto_ptr<Stand> get_stand() = 0;

 

public:

         virtual ~Framework()

         {

                   cout << "in the destructor of Framework..." << endl;

         }

};

 

// 1号相框

class No1Framework : public Framework

{

public:

         void set_frame(auto_ptr<Frame> frame)

         {

                   this->frame = frame;

         }

 

         auto_ptr<Frame> get_frame()

         {

                   if(frame.get())

                   {

                            return frame;

                   }

                   else

                   {

                            throw "frame没有被赋值";

                   }

         }

 

         void set_stand(auto_ptr<Stand> stand)

         {

                   this->stand = stand;

         }

 

         auto_ptr<Stand> get_stand()

         {

                   if(stand.get())

                   {

                            return stand;

                   }

                   else

                   {

                            throw "stand没有被赋值";

                   }

         }

 

public:

         ~No1Framework()

         {

                   cout << "in the destructor of No1Framework..." << endl;

         }

};

 

// 2号相框

class No2Framework : public Framework

{

public:

         void set_frame(auto_ptr<Frame> frame)

         {

                   this->frame = frame;

         }

 

         auto_ptr<Frame> get_frame()

         {

                   if(frame.get())

                   {

                            return frame;

                   }

                   else

                   {

                            throw "frame没有被赋值";

                   }

         }

 

         void set_stand(auto_ptr<Stand> stand)

         {

                   this->stand = stand;

         }

 

         auto_ptr<Stand> get_stand()

         {

                   if(stand.get())

                   {

                            return stand;

                   }

                   else

                   {

                            throw "stand没有被赋值";

                   }

         }

 

public:

         ~No2Framework()

         {

                   cout << "in the destructor of No2Framework..." << endl;

         }

};

 

// Builders

// 抽象类Builder,用以规范其子类的行为

class Builder

{

public:

         virtual void build_frame() = 0;

         virtual void build_stand() = 0;

         virtual auto_ptr<Framework> get_framework() = 0;

         // virtual auto_ptr<Framework> get_framework() const = 0;

         // 将会出现编译错误:

         // error C2558: class“std::auto_ptr<_Ty>”: 没有可用的复制构造函数或复制构造函数声明为“explicit”

         // 1>        with

         // 1>        [

         // 1>            _Ty=Framework

         // 1>        ]

         // 原因请看实现部分的解释。

public:

         virtual ~Builder()

         {

                   cout << "in the destructor of Builder..." << endl;

         }

};

 

// 1号相框的Builder

class No1FrameworkBuilder : public Builder

{

private:

         auto_ptr<Framework> fw;

 

public:

         No1FrameworkBuilder()

         {

                   // 在这里初始化fw

                   // 注意:绝对不能将fw赋值给另外一个auto_ptr<Framework>变量

                   auto_ptr<Framework> f(new No1Framework);

                   fw = f;

         }

 

         void build_frame()

         {

                   auto_ptr<Frame> f(new WoodenFrame);

                   fw->set_frame(f);

         }

 

         void build_stand()

         {

                   auto_ptr<Stand> s(new WoodenStand);

                   fw->set_stand(s);

         }

 

         auto_ptr<Framework> get_framework() //const

         {

                   // 注意上面的函数定义最后不能有const,因为最后返回的是一个auto_ptr<Framework>对象

                   // 因此为调用auto_ptr<Framework>的拷贝构造函数,由于auto_ptr的特点,拷贝或者赋值

                   // 会改变等号右边的操作数,即:

                   // auto_ptr<Framework> a(new ....);

                   // auto_ptr<Framework> b = a;

                   // 那么a对底层对象的控制权将会转交给ba自身将指向空对象,因此a发生了改变。

                   // const成员函数不能改变成员变量。正是因为这样的原因,不能将本成员函数设为const

                   return fw;

                  

                   // 如果本成员函数的内容如下,则可以将其设为const,因为ffw是一个临时对象,并非

                   // 本类之成员变量。

                   //auto_ptr<Framework> ffw(new No1Framework);

                   //return ffw;

         }

 

         ~No1FrameworkBuilder()

         {

                   cout << "in the destructor of No1FrameworkBuilder..." << endl;

         }

};

 

// 2号相框的Builder

class No2FrameworkBuilder : public Builder

{

private:

         auto_ptr<Framework> fw;

 

public:

         No2FrameworkBuilder()

         {

                   // 在这里初始化fw

                   // 注意:绝对不能将fw赋值给另外一个auto_ptr<Framework>变量

                   auto_ptr<Framework> f(new No2Framework);

                   fw = f;

         }

 

         void build_frame()

         {

                   auto_ptr<Frame> f(new SteelFrame);

                   fw->set_frame(f);

         }

 

         void build_stand()

         {

                   auto_ptr<Stand> s(new SteelStand);

                   fw->set_stand(s);

         }

 

         auto_ptr<Framework> get_framework() //const

         {

                   return fw;

         }

 

         ~No2FrameworkBuilder()

         {

                   cout << "in the destructor of No2FrameworkBuilder..." << endl;

         }

};

 

// Director

class Director

{

public:

         static auto_ptr<Framework> build_product(auto_ptr<Builder> builder)

         {

                   builder->build_frame();

                   builder->build_stand();

 

                   return builder->get_framework();

         }

};

 

// 测试代码:Builder.cpp

#include "Builder.h"

 

int main(int argc, char **argv)

{

         auto_ptr<Framework> f;

         auto_ptr<Builder> builder(new No1FrameworkBuilder);

 

         // 获取相框

         f = Director::build_product(builder);

         cout << (f->get_frame())->get_frame_name() << endl;

         cout << (f->get_stand())->get_stand_name() << endl;

 

         cout << "-------------------------------------------1" << endl;

         auto_ptr<Builder> temp(new No2FrameworkBuilder);

         builder = temp;

 

         // 获取相框

         f = Director::build_product(builder);

         cout << "-------------------------------------------2" << endl;

         cout << (f->get_frame())->get_frame_name() << endl;

         cout << (f->get_stand())->get_stand_name() << endl;

 

         return 0;

}

 

上述程序输出结果:

in the destructor of No1FrameworkBuilder...

in the destructor of Builder...

木质框

in the destructor of WoodenFrame...

in the destructor of Frame...

木质支撑

in the destructor of WoodenStand...

in the destructor of Stand...

-------------------------------------------1

in the destructor of No2FrameworkBuilder...

in the destructor of Builder...

in the destructor of No1Framework...

in the destructor of Framework...

-------------------------------------------2

钢质框

in the destructor of SteelFrame...

in the destructor of Frame...

钢质支撑

in the destructor of SteelStand...

in the destructor of Stand...

in the destructor of No2Framework...

in the destructor of Framework...

 

注意:12之间的析构函数调用,是因为f被重新赋值所至。

 

main函数中,只有带下划线的语句是变化的。

 

总之,Builder模式适合创建复杂对象,该复杂对象中包含多个子对象。

 

UML类图中的各个类和代码中的各个类之间的对应关系:

抽象复杂对象:

Product                                          < ---- >                         Framework

 

具体复杂对象:

ConcreteProduct                         < ---- >                         No1FrameworkNo2Framework

 

抽象部件:

Part1Part2                                 < ---- >                         FrameStand

 

具体部件:

ConcretePart11ConcretePart12              < ---- >                         WoodenFrameSteelFrame

ConcretePart21ConcretePart22                                                   WoodenStandWoodenFrame

 

抽象Builder

Builder                                           < ---- >                         Builder

 

具体Builder

ConcreteBuilder                          < ---- >                         No1FrameworkBuilderNo2FrameworkBuilder

 

Director

Director                                          < ---- >                         Director

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值