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

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


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

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

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


【基本结构】

建造者模式有下⾯⼏个关键⻆⾊:

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

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

C++ 设计模式之建造者模式_第1张图片


【使用场景】

使⽤建造者模式有下⾯⼏处优点:

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

        对应的,建造者模式适⽤于复杂对象的创建,当对象构建过程相对复杂时可以考虑使⽤建造者模式,但是当产品的构建过程发⽣变化时,可能需要同时修改指导类和建造者类,这就使得重构变得相对困难。
        建造者模式在现有的⼯具和库中也有着⼴泛的应⽤,⽐如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 
#include 
#include 

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(_bicycleBuilder);
            mountainBuilder->BuildFrame();
            mountainBuilder->BuildTires();
        
            return mountainBuilder->GetBicycle();
        }
        
        else if(bikeType == "road")
        {
            RoadBuilder *roadBuilder = dynamic_cast(_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.

你可能感兴趣的:(c++,设计模式,建造者模式)