【声明】本编码题目来源于【题目页面 (kamacoder.com)】
【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】
【简介】什么是建造者模式
????????建造者模式(也被成为?成器模式),是?种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,?建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义?个抽象的接?。具体的构建过程由实现了这些接?的具体建造者类来完成。同时有?个指导者类负责协调建造者的?作,按照?定的顺序或逻辑来执?构建步骤,最终?成产品。
????????举个例?,假如我们要创建?个计算机对象,计算机由很多组件组成,例如 CPU、内存、硬盘、显卡等。每个组件可能有不同的型号、配置和制造,这个时候计算机就可以被视为?个复杂对象,构建过程相对复杂,?我们使?建造者模式将计算机的构建过程封装在?个具体的建造者类中,?指导者类则负责指导构建的步骤和顺序。每个具体的建造者类可以负责构建不同型号或配置的计算机,客户端代码可以通过选择不同的建造者来创建不同类型的计算机,这样就可以根据需要构建不同表示的复杂对象,更加灵活。
【基本结构】
建造者模式有下??个关键??:
在客户端中,通过指导者来构建产品,?并不和具体建造者进?直接的交互。
【使用场景】
使?建造者模式有下??处优点:
????????对应的,建造者模式适?于复杂对象的创建,当对象构建过程相对复杂时可以考虑使?建造者模式,但是当产品的构建过程发?变化时,可能需要同时修改指导类和建造者类,这就使得重构变得相对困难。
????????建造者模式在现有的?具和库中也有着?泛的应?,?如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.