C++设计模式——建造者模式

来源:互联网 发布:openwrt 域名白名单 编辑:程序博客网 时间:2024/06/16 16:56

C++设计模式——建造者模式

    • C设计模式建造者模式
      • 概述
      • 场景描述
      • 类图描述
      • 代码实现
      • 优缺点
      • 适用场景

概述

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

场景描述

    现在有一个傻子要穿秋衣、秋裤、裤子和外套这四件衣服的场景,需要用代码来实现。我们脑子里第一个想法就是如下步骤:

        1.创建一个傻子的类,里面有穿衣这个动作的接口函数。然后初始化一个对象。

        2.分别创建秋衣、秋裤、裤子、外套的类,然后创建各自的对象。

        3.客户端调用:使用傻子类创建出来的对象,做穿秋衣、秋裤、裤子、外套这四个动作。

        4.大功告成。

    但是现在问题来了,场景中是傻子穿衣服,他穿衣可能就先把裤子和外套穿上了,然后再穿秋衣秋裤。这种情况是很有可能出现的,那之前的办法很明显是有缺陷的。 另外一个问题,当这个傻子万一是流落民间的富二代,只是装疯卖傻呢?当他被家族发现后要继承家业了,总不可能穿的衣服和之前衣服类创建出来的衣服一样吧?所以再次用代码描述该场景的时候,需要改动的地方就比较多了。

    建造者模式的定义是:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。如此一来,我们用建造者模式来解决一下该问题。

类图描述

Builder

  • IdiotDressing: 该模式中用于被构造的复杂对象。里面有具体构造该对象的方法。

  • IBuilder: 抽象构造类,申明了构造复杂对象所需要的方法。

  • BuildBeggerDressing…:具体的构造类,用来狗仔复杂对象的不同表示。并且提供一个检索产品的接口。

  • Director: 负责产品的构造。(场景中保证穿衣顺序的对错关键)。

代码实现

//产品类#ifndef IDIOTDRESS_H_#define IDIOTDRESS_H_#include <iostream>class IdiotDressing{public:    void SetUnderWare(std::string strUnderWare)    {        m_strUnderWare = strUnderWare;    }    void SetBriefs(std::string strBriefs)    {        m_strBriefs = strBriefs;    }    void SetPants(std::string strPants)    {        m_strPants = strPants;    }    void SetCoat(std::string strCoat)    {        m_strCoat = strCoat;    }    std::string GetUnderWare()    {        return m_strUnderWare;    }    std::string GetBriefs()    {        return m_strBriefs;    }    std::string GetPants()    {        return m_strPants;    }    std::string GetCoat()    {        return m_strCoat;    }private:    std::string m_strUnderWare;    std::string m_strBriefs;    std::string m_strPants;    std::string m_strCoat;};#endif
//建造者类#ifndef BUILDER_H_#define BUILDER_H_#include "IdiotDressing.h"class IBuilder{public:    virtual void BuildUnderware() = 0;    virtual void BuildBriefs() = 0;    virtual void BuildPants() = 0;    virtual void BuildCoat() = 0;    virtual IdiotDressing* GetIdiotDressing() = 0;};class BulidBeggerDressing : public IBuilder{public:    BulidBeggerDressing () {m_idiotDressing = new IdiotDressing();}    virtual void BuildUnderware(){ m_idiotDressing->SetUnderWare("脏的秋衣"); }    virtual void BuildBriefs() { m_idiotDressing->SetBriefs("破的秋裤"); }    virtual void BuildPants() { m_idiotDressing->SetPants("不合身的裤子"); }    virtual void BuildCoat() { m_idiotDressing->SetCoat("脏的外套"); }    virtual IdiotDressing* GetIdiotDressing(){ return m_idiotDressing; }private:    IdiotDressing* m_idiotDressing;};class BuildBossDressing : public IBuilder{public:    BuildBossDressing () {m_idiotDressing = new IdiotDressing();}    virtual void BuildUnderware() { m_idiotDressing->SetUnderWare("干净的秋衣"); }    virtual void BuildBriefs() { m_idiotDressing->SetBriefs("合身的秋裤"); }    virtual void BuildPants() { m_idiotDressing->SetPants("名牌的西裤"); }    virtual void BuildCoat() { m_idiotDressing->SetCoat("名牌的西装"); }    virtual IdiotDressing* GetIdiotDressing(){ return m_idiotDressing; }private:    IdiotDressing* m_idiotDressing;};#endif
//指挥者类#ifndef DIRECTOR_H_#define DIRECTOR_H_#include "Builder.h"class Director{public:    //实现建造流程    void Dressing(IBuilder* builder)    {        builder->BuildUnderware();        builder->BuildBriefs();        builder->BuildPants();        builder->BuildCoat();    }};#endif
#include <iostream>#include "Builder.h"#include "Director.h"using namespace std;#ifndef DELETE_OBJECT#define DELETE_OBJECT(Obj) \        {\        if (Obj) \            {\            delete (Obj); \            (Obj)=NULL;\            }\        }#endifint main(){    //创建两个建造者    IBuilder* pBeggerBuilder = new BulidBeggerDressing();    IBuilder* pBossBuilder = new BuildBossDressing();    //创建一个指挥者,并且创建相应的产品表现。    Director* pDirector = new Director();    pDirector->Dressing(pBeggerBuilder);    pDirector->Dressing(pBossBuilder);    IdiotDressing* pBeggerDress = pBeggerBuilder->GetIdiotDressing();    IdiotDressing* pBossDress = pBossBuilder->GetIdiotDressing();    cout << "Begger Dressing" << endl;    cout << "Underware:" << pBeggerDress->GetUnderWare().c_str() << endl;    cout << "Briefs:" << pBeggerDress->GetBriefs().c_str() << endl;    cout << "Pants:" << pBeggerDress->GetPants().c_str() << endl;    cout << "Coat:" << pBeggerDress->GetCoat().c_str() << endl<<endl<<endl;    cout << "Boss Dressing" << endl;    cout << "Underware:" << pBossDress->GetUnderWare().c_str() << endl;    cout << "Briefs:" << pBossDress->GetBriefs().c_str() << endl;    cout << "Pants:" << pBossDress->GetPants().c_str() << endl;    cout << "Coat:" << pBossDress->GetCoat().c_str() << endl;    DELETE_OBJECT(pBeggerBuilder);    DELETE_OBJECT(pBossBuilder);    DELETE_OBJECT(pDirector);    DELETE_OBJECT(pBeggerDress);    DELETE_OBJECT(pBossDress);    return 0;}

优缺点

优点:

  • 封装性好,易于扩展,如果有新的表现形式,只需要实现一个builder接口即可。符合开闭原则

  • 对复杂对象的建造流程可控。

缺点:

  • 只针对同类产品的建造。有局限性。

适用场景

适用于对象内部比较复杂的复杂对象的构建。