建造者模式加模板模式实现建造小人 C++

本文深入讲解建造者模式的原理及应用,通过实例演示如何利用该模式简化复杂对象的构建过程,实现不同表示的灵活组装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说下对建造者模式的理解:
建造者模式:将一个复杂的对象的构建与他的表示分离, 使得同样的构建过程可以创建不同的表示。
它使用builder 构建各个部分的抽象接口, 由子类具体实现。 通过director 指挥构建的过程, 这个构建的过程一般是相对比较固定的。
他主要用来创建一些比较复杂的对象,并且这些对象之间的建造顺序通常是稳定的, 但对象内部的构建通常面临比较复杂的变化。
他使得建造代码和表示代码分离, 隐藏了产品组装的方式, 如果需要改变一个产品的内部表示, 只需要在定义一个具体的建造者就可以了。

个人感觉, 他和外观模式有一定的相似性, 或者说, 感觉很像,外观模式, 是为一组复杂的类提供一组统一的访问方式, 符合迪米特原则和依赖倒转原则。 而这里的建造者模式, 感觉也是有一堆构建部件的子类, 通过director这个构建者, 实现组装的, 用户不用再关注部件构造这些复杂的过程。

通常建造者模式的builder定义一组抽象接口, 由子类去具体实现, 在我们这个例子中, 为避免代码复杂化, 我们进行了改造, 融入了模板模式的思想, 将一部分公共元素,提取到基类,子类只要实现部分差异表现即可。

下面是UML图:
这里写图片描述

运行效果图:
这里写图片描述

下面是代码部分:
product.h

#ifndef _PRODUCT_H_
#define _PRODUCT_H_

#include <string>
#include <iostream>

using std::cout;
using std::endl;
using std::string;

/************************************************************************/
/* 产品类, 建造者模式最终生成的对象                                    */
/************************************************************************/

class CProduct{
public:
    string Description() const { return description; }
    void Description(string val) { description = val; }

    void display(){ cout << Description() << endl; }
private:
    string description; 
};


#endif // _PRODUCT_H_

productbuilder.h

#ifndef _PERSONBUILDER_H_
#define _PERSONBUILDER_H_

#include "product.h"
#include <string>
#include <memory>

using std::string;
using std::shared_ptr;

/************************************************************************/
/* 建造者的细节接口             +  模板模式                              */
/************************************************************************/
class CPersonBuilder{
public:
    CPersonBuilder() : product(new CProduct){}

    /************************************************************************/
    /* 建造的主体部件, 模板                                                */
    /************************************************************************/
    void BuildHead();
    void BuildBody();
    void BuildArmLeft();
    void BuildArmRight();
    void BuildLegLeft();
    void BuildLegRight();

    // display
    shared_ptr<CProduct> getResult() const { return product; }

private:
    /************************************************************************/
    /* 具体实现的接口                                                       */
    /************************************************************************/
    virtual string head() = 0;
    virtual string body() = 0;
    virtual string armleft() = 0;
    virtual string armright() = 0;
    virtual string legleft() = 0;
    virtual string legright() = 0;

private:
    shared_ptr<CProduct> product;
};

/************************************************************************/
/*              具体的建造方式       thin                               */
/************************************************************************/
class CPersonThinBuilder : public CPersonBuilder{
private:
    string head(){ return "head\t"; }
    string body(){ return "thin body\t"; }
    string armleft(){ return "arm left\t"; }
    string armright(){ return "arm right\t"; }
    string legleft(){ return "leg left\t"; }
    string legright(){ return "leg right\t"; }
};

/************************************************************************/
/*              具体的建造方式       fat                                */
/************************************************************************/
class CPersonFatBuilder : public CPersonBuilder{
private:
    string head(){ return "head\t"; }
    string body(){ return "fat body\t"; }
    string armleft(){ return "arm left\t"; }
    string armright(){ return "arm right\t"; }
    string legleft(){ return "leg left\t"; }
    string legright(){ return "leg right\t"; }
};

#endif // _PERSONBUILDER_H_

productbuilder.cpp

#include "personbuilder.h"

/************************************************************************/
/* CPersonBuilder     的基本构架                                        */
/************************************************************************/
void CPersonBuilder::BuildHead()
{
    string tmp = product->Description();
    product->Description(tmp + head());
}

void CPersonBuilder::BuildBody()
{
    string tmp = product->Description();
    product->Description(tmp + body());
}

void CPersonBuilder::BuildArmLeft()
{
    string tmp = product->Description();
    product->Description(tmp + armleft());
}

void CPersonBuilder::BuildArmRight()
{
    string tmp = product->Description();
    product->Description(tmp + armright());
}

void CPersonBuilder::BuildLegLeft()
{
    string tmp = product->Description();
    product->Description(tmp + legleft());
}

void CPersonBuilder::BuildLegRight()
{
    string tmp = product->Description();
    product->Description(tmp + legright());
}

persondirector.h

#include "personbuilder.h"
#include <memory>

using std::shared_ptr;

class CPersonDirector{
public:
    //************************************
    // Method:    CreateThinPerson
    // FullName:  CPersonDirector::CreateThinPerson
    // Access:    public 
    // Returns:   
    // Qualifier: 创建一个 ThinPerson 对象
    //************************************
    void CreatePerson(CPersonBuilder * builder){
        builder->BuildHead();
        builder->BuildBody();
        builder->BuildArmLeft();
        builder->BuildArmRight();
        builder->BuildLegLeft();
        builder->BuildLegRight();
    }
};

#endif // _PERSONDIRECTOR_H_

main.cpp

#include "persondirector.h"

#include <iostream>
#include <memory>
using namespace std;

int main(){
    shared_ptr<CPersonBuilder> builderFat(new CPersonFatBuilder);
    shared_ptr<CPersonBuilder> builderThin(new CPersonThinBuilder);
    CPersonDirector director;

    director.CreatePerson(builderFat.get());    
    shared_ptr<CProduct> product = builderFat->getResult();
    product->display();

//  product = builderThin->getResult();
//  product->display();

    director.CreatePerson(builderThin.get());
    product = builderThin->getResult();
    product->display();

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值