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

发布时间:2024年01月16日

【声明】本编码题目来源于【题目页面 (kamacoder.com)


【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】

【简介】什么是建造者模式

????????建造者模式(也被成为?成器模式),是?种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,?建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义?个抽象的接?。具体的构建过程由实现了这些接?的具体建造者类来完成。同时有?个指导者类负责协调建造者的?作,按照?定的顺序或逻辑来执?构建步骤,最终?成产品。
????????举个例?,假如我们要创建?个计算机对象,计算机由很多组件组成,例如 CPU、内存、硬盘、显卡等。每个组件可能有不同的型号、配置和制造,这个时候计算机就可以被视为?个复杂对象,构建过程相对复杂,?我们使?建造者模式将计算机的构建过程封装在?个具体的建造者类中,?指导者类则负责指导构建的步骤和顺序。每个具体的建造者类可以负责构建不同型号或配置的计算机,客户端代码可以通过选择不同的建造者来创建不同类型的计算机,这样就可以根据需要构建不同表示的复杂对象,更加灵活。


【基本结构】

建造者模式有下??个关键??:

  • 产品Product :被构建的复杂对象, 包含多个组成部分。
  • 抽象建造者Builder : 定义构建产品各个部分的抽象接?和?个返回复杂产品的?法getResult
  • 具体建造者Concrete Builder :实现抽象建造者接?,构建产品的各个组成部分,并提供?个?法返回最终的产品。
  • 指导者Director :调?具体建造者的?法,按照?定的顺序或逻辑来构建产品。

在客户端中,通过指导者来构建产品,?并不和具体建造者进?直接的交互。


【使用场景】

使?建造者模式有下??处优点:

  • 使?建造者模式可以将?个复杂对象的构建与其表示分离,通过将构建复杂对象的过程抽象出来,可以使客户端代码与具体的构建过程解耦
  • 同样的构建过程可以创建不同的表示,可以有多个具体的建造者(相互独?),可以更加灵活地创建不同组合的对象。

????????对应的,建造者模式适?于复杂对象的创建,当对象构建过程相对复杂时可以考虑使?建造者模式,但是当产品的构建过程发?变化时,可能需要同时修改指导类和建造者类,这就使得重构变得相对困难。
????????建造者模式在现有的?具和库中也有着?泛的应?,?如JUnit 中的测试构建器TestBuilder 就采?了建造者模式,?于构建测试对象。


【C++ 编码部分】

1.题目描述

????????小明家新开了一家自行车工厂,用于使用自行车配件(车架 frame 和车轮 tires )进行组装定制不同的自行车,包括山地车和公路车。山地车使用的是Aluminum Frame(铝制车架)和Knobby Tires(可抓地轮胎),公路车使用的是 Carbon Frame (碳车架)和 Slim Tries。现在它收到了一笔订单,要求定制一批自行车,请你使用【建造者模式】告诉小明这笔订单需要使用那些自行车配置吧。

2.输入描述

????????输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示订单的数量。?接下来的 N 行,每行输入一个字符串,字符串表示客户的自行车需求。字符串可以包含关键词 "mountain" 或 "road",表示客户需要山地自行车或公路自行车。

3.输出描述

????????对于每笔订单,输出该订单定制的自行车配置。

4.C++实例编码

/**
* @version Copyright (c) 2024 NCDC, Servo。 Unpublished - All rights reserved
* @file BulidMode.hpp
* @brief 建造者模式
* @autor 写代码的小恐龙er
* @date 2024/01/09
*/

// 头文件
#include <iostream>
#include <vector>
#include <string>

using namespace std;

// 前置声明
// 产品类
class Bicycle;
// 抽象建造者接口类
class BicycleBuilder;
// 具体建造者 -- 山地自行车 和 公路自行车
class MountainBuilder;
class RoadBuilder;
// 指导者类 -- 管理类
class BycicleDirector;

// 产品类
class Bicycle
{
// 成员属性 -- 组成部分(一般成员属性放在私有部分 并提供接口)
private:
    string _frame;  // 车架
    string _tires;  // 车轮

// 成员函数
public:
    // 一般需要给私有的成员属性提供读写接口
    string GetFrame(){
        return this->_frame;
    }
    void SetFrame(string frame){
        this->_frame = frame;
    }
    
    string GetTires(){
        return this->_tires;
    }
    void SetTires(string tires){
        this->_tires = tires;
    }
    
    // 输出组成部件
    void PrintString(){
        std::cout <<  _frame + " " + _tires << endl;
    }
    
};

// 抽象建造者接口类
class BicycleBuilder
{
public:
    // 接口 声明为 纯虚函数
    virtual void BuildFrame() = 0;
    virtual void BuildTires() = 0;
    virtual Bicycle *GetBicycle() = 0;
};

// 具体建造者1 -- 山地自行车
class MountainBuilder : public BicycleBuilder
{
// 成员属性
private:
    Bicycle *_bicycle = nullptr;  // 产品

// 构造函数和析构函数
public:
    // 构造函数加上explicit 关键词 防止隐式构造
    explicit MountainBuilder(){
        _bicycle = new Bicycle();
    }
    // 在堆区开辟的内存一定要自己释放
    ~MountainBuilder(){
        if(_bicycle != nullptr){
            delete _bicycle;
            _bicycle = nullptr;
        }
    }
// 成员函数
public:
    //  具体的接口函数
    void BuildFrame() override { 
        _bicycle->SetFrame("Aluminum Frame");
    }
    void BuildTires() override {
        _bicycle->SetTires("Knobby Tires");
    }
    Bicycle *GetBicycle() override {
        return this->_bicycle;
    }
};

// 具体建造者2 -- 公路自行车
class RoadBuilder : public BicycleBuilder
{
// 成员属性
private:
    Bicycle *_bicycle = nullptr;  // 产品

// 构造函数和析构函数
public:
    // 构造函数加上explicit 关键词 防止隐式构造
    explicit RoadBuilder(){
        _bicycle = new Bicycle();
    }
    // 在堆区开辟的内存一定要自己释放
    ~RoadBuilder(){
        if(_bicycle != nullptr){
            delete _bicycle;
            _bicycle = nullptr;
        }
    }
// 成员函数
public:
    //  具体的接口函数
    void BuildFrame() override { 
        _bicycle->SetFrame("Carbon Frame");
    }
    void BuildTires() override {
        _bicycle->SetTires("Slim Tires");
    }
    Bicycle *GetBicycle() override {
        return this->_bicycle;
    }
};

// 指导者类 -- 自行车管理者
class BycicleDirector
{
// 成员属性
private:
    BicycleBuilder *_bicycleBuilder = nullptr;  // 产品

// 构造函数和析构函数
public:
    // 构造函数加上explicit 关键词 防止隐式构造
    explicit BycicleDirector(BicycleBuilder *bicycle){ 
        this->_bicycleBuilder = bicycle;
    }
// 调用方法去构建产品
public:    
    Bicycle* Construct(string bikeType){
        // 通过具体的某个自行车建造者 来构建 具体的自行车
        if(bikeType == "mountain")
        {
            MountainBuilder *mountainBuilder = dynamic_cast<MountainBuilder *>(_bicycleBuilder);
            mountainBuilder->BuildFrame();
            mountainBuilder->BuildTires();
        
            return mountainBuilder->GetBicycle();
        }
        
        else if(bikeType == "road")
        {
            RoadBuilder *roadBuilder = dynamic_cast<RoadBuilder *>(_bicycleBuilder);
            roadBuilder->BuildFrame();
            roadBuilder->BuildTires();
        
            return roadBuilder->GetBicycle();
        }
        else return nullptr;
    }
};


int main()
{
    // 订单数量
    int orderNum = 0;
    // 输入的自行车类型
    string bikeType = "";
    // 已有自行车类型
    string mountain = "mountain";
    string road = "road";
    // 输入订单数量
    std::cin >>  orderNum;
    
    for(int i = 0; i < orderNum; i++)
    {
        // 自行车类型
        std::cin >> bikeType;
        
        // 自行车建造者和 指导者
        BicycleBuilder *builder = nullptr;
        BycicleDirector *bycicleDirector = nullptr;
        
        if(bikeType == mountain)
        {
            // 创建 山地自行车 工厂 【向上类型转换】
            builder = new MountainBuilder();
        }
        else if(bikeType == road)
        {
            // 创建 公路自行车 工厂  【向上类型转换】
            builder = new RoadBuilder();
        }
        else continue;
        
        // 当创建好具体的自行车建造类后  开始具体的构造
        // 自行车生产的  指导类 
        bycicleDirector= new BycicleDirector(builder);
            
        // 生产出具体的自行车
        Bicycle *bicycle = bycicleDirector->Construct(bikeType);
        
        // 输出这辆自行车的信息
        bicycle->PrintString();
        
        // 用完记得析构掉堆区开辟的内存
        delete builder;
        builder = nullptr;
        delete bycicleDirector;
        bycicleDirector = nullptr;
    }
    return 0;
}

......

To be continued.

文章来源:https://blog.csdn.net/K1_uestc/article/details/135474753
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。