首页 > 编程语言 >c++ 设计模式:建造者模式

c++ 设计模式:建造者模式

时间:2024-05-24 17:18:50浏览次数:21  
标签:string void 建造 c++ 构建 virtual strno 设计模式 模型

建造者模式(Builder Pattern)是一种创建型设计模式,它允许你构造复杂对象步骤分解。你可以不同的步骤中使用不同的方式创建对象,且对象的创建与表示是分离的。这样,同样的构建过程可以创建不同的表示。

举例说明:

#include <iostream>
//#include <map>
//#include <stack>
#include <vector>
#include <sstream>

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996) 

namespace _nmsp1
{
    //怪物父类
    class Monster
    {
    public:
        virtual ~Monster() {} //做父类时析构函数应该为虚函数
        //void Assemble(string strmodelno) //参数:模型编号,形如:“1253679201245”等。每些位的组合都有一些特别的含义,这里不需要探究。
        //{
        //    LoadTrunkModel(strmodelno.substr(4, 3)); //载入躯干模型,截取某部分字符串以表示躯干模型的编号
        //    LoadHeadModel(strmodelno.substr(7, 3)); //载入头部模型并挂接到躯干模型上
        //    LoadLimbsModel(strmodelno.substr(10, 3)); //载入四肢模型并挂接到躯干模型上
        //}

        //virtual void LoadTrunkModel(string strno) = 0; //这里也可以写成一个空函数,子类决定是否重新实现
        //virtual void LoadHeadModel(string strno) = 0;
        //virtual void LoadLimbsModel(string strno) = 0;
    };

    //亡灵类怪物
    class M_Undead :public Monster
    {
    /*public:
        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入亡灵类怪物的躯干部位模型,需要调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入亡灵类怪物的头部模型并挂接到躯干部位,需要调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入亡灵类怪物的四肢模型并挂接到躯干部位,需要调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }*/
    };

    //元素类怪物
    class M_Element :public Monster
    {
    /*public:
        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入元素类怪物的躯干部位模型,需要调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入元素类怪物的头部模型并挂接到躯干部位,需要调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入元素类怪物的四肢模型并挂接到躯干部位,需要调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }*/
    };

    //机械类怪物
    class M_Mechanic :public Monster
    {
    /*public:
        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入机械类怪物的躯干部位模型,需要调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入机械类怪物的头部模型并挂接到躯干部位,需要调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入机械类怪物的四肢模型并挂接到躯干部位,需要调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
        }*/
    };
    //----------------------------
    //怪物构建器父类
    class MonsterBuilder
    {
    public:
        virtual ~MonsterBuilder() {} //做父类时析构函数应该为虚函数
        //void Assemble(string strmodelno) //参数:模型编号,形如:“1253679201245”等。每些位的组合都有一些特别的含义,这里不需要探究。
        //{
        //    LoadTrunkModel(strmodelno.substr(4, 3)); //载入躯干模型,截取某部分字符串以表示躯干模型的编号
        //    LoadHeadModel(strmodelno.substr(7, 3)); //载入头部模型并挂接到躯干模型上
        //    LoadLimbsModel(strmodelno.substr(10, 3)); //载入四肢模型并挂接到躯干模型上
        //}

        //返回指向Monster类的成员变量指针m_pMonster,当一个复杂的对象构建完成后,可以通过该成员函数把对象返回。
        Monster* GetResult()
        {
            return m_pMonster;
        }

        virtual void LoadTrunkModel(string strno) = 0; //这里也可以写成一个空函数,子类决定是否重新实现
        virtual void LoadHeadModel(string strno) = 0;
        virtual void LoadLimbsModel(string strno) = 0;

    protected:
        Monster* m_pMonster; //指向Monster类的成员变量指针
    };

    //----------
    //亡灵类怪物构建器类
    class M_UndeadBuilder :public MonsterBuilder
    {
    public:
        M_UndeadBuilder() //构造函数
        {
            m_pMonster = new M_Undead();
        }

        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入亡灵类怪物的躯干部位模型,需要m_pMonster指针调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //具体要做的事情其实是委托给怪物子类完成,委托指把本该自己实现的功能转给其他类实现
            //m_pMonster->......略
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入亡灵类怪物的头部模型并挂接到躯干部位,需要m_pMonster指针调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入亡灵类怪物的四肢模型并挂接到躯干部位,需要m_pMonster指针调用M_Undead类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
    };

    //元素类怪物构建器类
    class M_ElementBuilder :public MonsterBuilder
    {
    public:
        M_ElementBuilder() //构造函数
        {
            m_pMonster = new M_Element();
        }

        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入元素类怪物的躯干部位模型,需要m_pMonster指针调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;            
            //m_pMonster->......略
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入元素类怪物的头部模型并挂接到躯干部位,需要m_pMonster指针调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入元素类怪物的四肢模型并挂接到躯干部位,需要m_pMonster指针调用M_Element类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
    };

    //机械类怪物构建器类
    class M_MechanicBuilder :public MonsterBuilder
    {
    public:
        M_MechanicBuilder() //构造函数
        {
            m_pMonster = new M_Mechanic();
        }

        virtual void LoadTrunkModel(string strno)
        {
            cout << "载入机械类怪物的躯干部位模型,需要m_pMonster指针调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
        virtual void LoadHeadModel(string strno)
        {
            cout << "载入机械类怪物的头部模型并挂接到躯干部位,需要m_pMonster指针调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
        virtual void LoadLimbsModel(string strno)
        {
            cout << "载入机械类怪物的四肢模型并挂接到躯干部位,需要m_pMonster指针调用M_Mechanic类或其父类中其他诸多成员函数,逻辑代码略......" << endl;
            //m_pMonster->......略
        }
    };

    //------------------
    //指挥者类
    class MonsterDirector
    {
    public:
        MonsterDirector(MonsterBuilder* ptmpBuilder) //构造函数
        {
            m_pMonsterBuilder = ptmpBuilder;
        }

        //指定新的构建器
        void SetBuilder(MonsterBuilder* ptmpBuilder)
        {
            m_pMonsterBuilder = ptmpBuilder;
        }

        //原MonsterBuilder类中的Assemble成员函数
        Monster *Construct(string strmodelno) //参数:模型编号,形如:“1253679201245”等。每些位的组合都有一些特别的含义,这里不需要探究。
        {
            m_pMonsterBuilder->LoadTrunkModel(strmodelno.substr(4, 3)); //载入躯干模型,截取某部分字符串以表示躯干模型的编号
            m_pMonsterBuilder->LoadHeadModel(strmodelno.substr(7, 3)); //载入头部模型并挂接到躯干模型上
            m_pMonsterBuilder->LoadLimbsModel(strmodelno.substr(10, 3)); //载入四肢模型并挂接到躯干模型上
            return m_pMonsterBuilder->GetResult(); //返回构建后的对象
        }
    private:
        MonsterBuilder* m_pMonsterBuilder; //指向所有构建器类的父类
    };
}
int main()
{

    /*
    _nmsp1::Monster* pmonster = new _nmsp1::M_Element(); //创建一只元素类怪物
    pmonster->Assemble("1253679201254");

    //释放资源
    delete pmonster;
    */
   
    _nmsp1::MonsterBuilder* pMonsterBuilder = new _nmsp1::M_UndeadBuilder(); //创建亡灵类怪物构建器对象
    _nmsp1::MonsterDirector* pDirector = new _nmsp1::MonsterDirector(pMonsterBuilder);
    _nmsp1::Monster* pMonster = pDirector->Construct("1253679201254"); //这里就构建出了一个完整的怪物对象

    //释放资源
    delete pMonster;
    delete pDirector;
    delete pMonsterBuilder;
   
}

建造者(Builder)模式

   构建器/构建者/生成器模式-创建型模式。     通常用于创建比较复杂的对象    (1)一个具体实现范例的逐步重构           怪物:亡灵类,元素类,机械类           怪物组成:头部、躯干(颈部、尾巴)、肢体 三个部位组成。           编码步骤:将怪物躯干部模型信息读入内存。将怪物的头部和四肢模型信息读入内存。将头部和四肢模型以正确的位置和方向挂接到躯干部位。  最终装配出完整的怪物模型。          Assemble、LoadTrunkModel、LoadHeadModel、LoadLimbsModel称为构建过程相关的函数。          引入与怪物类同层次的相关构建器类,把怪物类中代码搬到相关的构建器类中。 (2)引入建造者(Builder)模式          引入建造者(Builder)模式定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。           MonsterBuilder类就是对象的构建,Monster类是对象的表示。     建造者模式包含四种角色:       a)Builder(抽象构建器):这里指MonsterBuilder。       b)ConcreteBuilder(具体构建器):这里指M_UndeadBuilder、M_ElementBuilder、M_MechanicBuilder类。       c)Product(产品):这里指M_Undead、M_Element、M_Mechanic类。       d)Director(指挥者):MonsterDirector类。     复杂的东西就考虑拆解,简单的东西就考虑合并。   (4)建造者模式的总结:用于分步骤构建一个复杂对象,其中构建步骤是一个稳定算法(构建算法)。         何时使用:            a)产品对象内部结构复杂,产品往往由多个零件组成。            b)需要创建的产品对象内部属性互相依赖,需要指定创建次序。            c)当创建复杂对象的步骤(过程)应该独立于该对象的组成部分;            d)将复杂对象的创建和使用分离,使相同的创建过程可以创建不同的产品。        指挥者类作用:           a)通过部件以指定的顺序来构建整个产品(控制了构建过程)           b)通过提供Construct接口隔离了客户端与具体构建过程所必须要调用的类的成员函数之间的关联。       建造者模式优点:          a)产品构建和产品表现上的分离。构建算法可以被复用。          b)向客户端隐藏了产品内部的表现。         c)产品的实现可以被随时替换。     建造者模式缺点:        a)要求所创建的产品有比较多的共同点,创建步骤(组成部分)要大致相同。        b)该模式涉及到很多类。Director,Builder对象。对于理解和学习具有一定门槛。   https://blog.csdn.net/weixin_42097108/article/details/133609448  

标签:string,void,建造,c++,构建,virtual,strno,设计模式,模型
From: https://www.cnblogs.com/bwbfight/p/18211352

相关文章

  • C++友元和动态内存
    在C++中,友元机制允许一个类将其非公有成员的访问权限授予指定的函数或者类。然而,滥用友元会破坏封装性,导致可维护性和安全性问题。动态内存指的是在程序运行时分配和释放内存,通常通过使用new和delete操作符在C++中管理。下面是一个简单的例子,展示了如何在类中使用友元函数来访问......
  • C++/Qt桌面应用学习路线参考
    ......
  • c++对象存放区域
    在C++中,对象的存放位置通常取决于对象的生存周期和分配方式。C++中的对象可以存放在以下几个主要的内存区域:栈(Stack):自动变量和局部对象通常存储在栈上。栈是一种后进先出(LIFO)的数据结构,它由编译器自动管理,当函数调用结束时,栈上的局部对象会自动被销毁。堆(Heap):动态分配......
  • C++-函数
    函数(Function):是一个提前封装好的、可重复使用的、完成特定功能的独立代码单元。特点:提前封装、可重复使用的、完成特定功能将针对特定功能的、有重复使用需求的代码,提前封装到函数内,在需要的时候随时调用。基础函数语法return语句执行后,函数立刻结束函数不可定义在mai......
  • Educator:C++面向对象-STL实训
    第1关:病毒复制任务描述本关任务:设计一个病毒类。相关知识本关涉及到的内容如下:拷贝构造函数重载!=和==运算符拷贝构造函数当一个构造函数的唯一一个参数就是它所在类的引用时,这个构造函数就是一个拷贝构造函数编程要求设计一个病毒Virus类,它的内部有一个Gen变量,代表......
  • 重构MQ处理架构:MVEL表达式和责任链设计模式应用实践
    重构MQ处理架构:MVEL表达式和责任链设计模式应用实践https://mp.weixin.qq.com/s/_UZhfi1BiGNHQAHWhGus8Q 3.责任链设计模式【3.1定义】责任链模式(ChainofResponsibility)又名职责链模式,是一种行为设计模式,它允许你构建一个由多个对象组成的链,每个对象都有机会处理请求,或者......
  • 浅谈C++函数
    目录一、函数的概念二、调用函数的两个前提三、函数传参的三种形式四、函数返回类型一、函数的概念函数是C++程序的基本模块,通常一个C++程序由一个或多个函数组成。函数可以完成用户指定的任务,一般分为库函数和用户自定义的函数。函数由函数头和函数体组成,函数头中包......
  • 【C++】两个类的相互引用_c++ 类相互引用
    有时候在设计数据结构的时候,可能会遇到两个类需要相互引用的情形。比如类A有类型为B的成员,而类B又有类型为A的成员。那么这种情形下,两个类的设计上需要注意什么呢?同一文件尝试方案将A和B的定义都放在一个文件中,例如:#include<iostream>classA{public:......
  • C++Linux系统编程——文件和目录操作函数
    stat函数(重要)#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>​intstat(constchar*path,structstat*buf);intlstat(constchar*pathname,structstat*buf);功能: 获取文件状态信息 stat和lstat的区别:   当文件是一个符号......
  • 【C++初阶】—— 类和对象 (上)
    ......