【设计模式】建造者/生成器模式(Builder Pattern)

本文探讨了建造者模式和模板方法模式的区别与联系,通过实例对比两种设计模式的应用场景,阐述了它们在面向对象编程中如何帮助开发者解决复杂对象创建与方法调用的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.1 模式说明

建造者(或称生成器)模式

将复杂对象的构建分解为一系列简单的部件构建,并将这些部件的构建封装在具体建造者中,使得构建过程变得可控且灵活。(不同的类型对象 可以选择不同的部件组合以及部件的具体构造内容)


1.2 作用(解决的问题)


• 方便用户创建不同的对象。
• 代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)

例如:

房屋House对象。 建造房屋, 用到的部件有墙、房门、窗户、地板、屋顶,可能还需要院子、车库(garage)、暖气、游泳池等。

你可以写一个构造函数,把建造房屋可能用到的部件全部做为参数,建造不同规格的房子,就填不同的参数,例如建造不同的房子 :

simplehomeBuild(墙,房,窗,地板,屋顶,NULL,NULL,NULL……)

betterhomeBuild(墙,房,窗,地板,屋顶,暖气,NULL,游泳池……)


通常情况下, 绝大部分的参数都没有使用, 这使得对于构造函数的调用十分不简洁。 例如, 只有很少的房子有游泳池, 因此与游泳池相关的参数十之八九是毫无用处的。

解决方法:

将复杂房子的构建分解为一系列简单的部件构建,建筑不同的房子时,只需调用所需创建的部件函数即可:

示例代码: 

#include <iostream>
#include <memory>
#include <vector>
#include <string>

// 产品类:House
class House {
public:
    void addPart(const std::string& part) { parts.push_back(part); }
    void show() const {
        std::cout << "House with: ";
        for (const auto& part : parts) {
            std::cout << part << ", ";
        }
        if (!parts.empty()) std::cout << "\b\b. \n"; // 移除最后多余的逗号和空格
    }

private:
    std::vector<std::string> parts;
};

// 抽象建造者类:HouseBuilder
class HouseBuilder {
public:
    virtual ~HouseBuilder() = default;
    virtual void buildWalls() = 0;
    virtual void buildDoors() = 0;
    virtual void buildWindows() = 0;
    virtual void buildFloor() = 0;
    virtual void buildRoof() = 0;

    // Optional methods can be overridden as needed
    virtual void buildYard() {}
    virtual void buildGarage() {}
    virtual void buildHeating() {}
    virtual void buildSwimmingPool() {}

    virtual std::unique_ptr<House> getResult() = 0;
};

// 具体建造者类1:SimpleHouseBuilder
class SimpleHouseBuilder : public HouseBuilder {
public:
    SimpleHouseBuilder() : m_house(std::make_unique<House>()) {}
    void buildWalls() override { m_house->addPart("walls"); }
    void buildDoors() override { m_house->addPart("doors"); }
    void buildWindows() override { m_house->addPart("windows"); }
    void buildFloor() override { m_house->addPart("floor"); }
    void buildRoof() override { m_house->addPart("roof"); }
    std::unique_ptr<House> getResult() override { return std::move(m_house); }

private:
    std::unique_ptr<House> m_house;
};

// 具体建造者类2:BetterHouseBuilder (多了一个游泳池的构建)
class BetterHouseBuilder : public HouseBuilder {
public:
    BetterHouseBuilder() : m_house(std::make_unique<House>()) {}
    void buildWalls() override { m_house->addPart("walls"); }
    void buildDoors() override { m_house->addPart("doors"); }
    void buildWindows() override { m_house->addPart("windows"); }
    void buildFloor() override { m_house->addPart("floor"); }
    void buildRoof() override { m_house->addPart("roof"); }
    void buildSwimmingPool() override { m_house->addPart("swimming pool"); }
    void buildHeating() override { m_house->addPart("heating system"); }
    std::unique_ptr<House> getResult() override { return std::move(m_house); }

private:
    std::unique_ptr<House> m_house;
};

// 指挥者类:Director
class Director {
public:
    template<typename T>
    void construct(T& builder) {
        builder.buildWalls();
        builder.buildDoors();
        builder.buildWindows();
        builder.buildFloor();
        builder.buildRoof();
    }
};

int main() {
    Director director;

    // 构建简单房屋
    SimpleHouseBuilder simpleHomeBuilder;
    director.construct(simpleHomeBuilder);
    auto simpleHome = simpleHomeBuilder.getResult();
    simpleHome->show();

    // 构建更高级的房屋
    BetterHouseBuilder betterHomeBuilder;
    director.construct(betterHomeBuilder);
    betterHomeBuilder.buildSwimmingPool(); // 可选步骤
    betterHomeBuilder.buildHeating();      // 可选步骤
    auto betterHome = betterHomeBuilder.getResult();
    betterHome->show();

    return 0;
}

示例代码2:

如果构建过程相对简单且不需要太多定制化,下面这种方法(流利接口风格)可能会更受欢迎,因为它提供了更简洁的API和更好的用户体验。

#include <iostream>
#include <string>
 
class House {
private:
    // 私有成员变量
    std::string wall;
    std::string door;
    std::string window;
    std::string floor;
    std::string roof;
    std::string garage;
    std::string heating;
    std::string swimmingPool;
 
    // 私有构造函数,防止直接实例化
    House() {}
 
public:
    // 友元声明,以便Builder类访问私有成员
    friend class HouseBuilder;
 
    // 显示房屋信息
    void show() const {
        std::cout << "House{" <<
            "wall='" << wall << "', " <<
            "door='" << door << "', " <<
            "window='" << window << "', " <<
            "floor='" << floor << "', " <<
            "roof='" << roof << "', " <<
            "garage='" << garage << "', " <<
            "heating='" << heating << "', " <<
            "swimmingPool='" << swimmingPool << "'" <<
            "}" << std::endl;
    }
};
 
// 建造者类:HouseBuilder
class HouseBuilder {
private:
    House house;
 
public:
    // 设置房屋各个部件的方法,返回Builder自身以便链式调用
    HouseBuilder& setWall(const std::string& wall) {
        house.wall = wall;
        return *this;
    }
 
    HouseBuilder& setDoor(const std::string& door) {
        house.door = door;
        return *this;
    }
 
    HouseBuilder& setWindow(const std::string& window) {
        house.window = window;
        return *this;
    }
 
    HouseBuilder& setFloor(const std::string& floor) {
        house.floor = floor;
        return *this;
    }
 
    HouseBuilder& setRoof(const std::string& roof) {
        house.roof = roof;
        return *this;
    }
 
    HouseBuilder& setGarage(const std::string& garage) {
        house.garage = garage;
        return *this;
    }
 
    HouseBuilder& setHeating(const std::string& heating) {
        house.heating = heating;
        return *this;
    }
 
    HouseBuilder& setSwimmingPool(const std::string& swimmingPool) {
        house.swimmingPool = swimmingPool;
        return *this;
    }
 
    // 构建并返回House对象
    House build() {
        return house;
    }
};
 
// 客户端代码
int main() {
    // 构建一个简单的房子
    House simpleHome = HouseBuilder()
        .setWall("Simple Wall")
        .setDoor("Wooden Door")
        .setWindow("Small Window")
        .setFloor("Wooden Floor")
        .setRoof("Tiled Roof")
        .build();
 
    simpleHome.show();
 
    // 构建一个更好的房子
    House betterHome = HouseBuilder()
        .setWall("Reinforced Wall")
        .setDoor("Steel Door")
        .setWindow("Large Window")
        .setFloor("Marble Floor")
        .setRoof("Slate Roof")
        .setHeating("Central Heating")
        .setSwimmingPool("Outdoor Swimming Pool")
        .build();
 
    betterHome.show();
 
    return 0;
}

你提供的代码确实可以用来说明建造者模式,而且它实

参考:Carson带你学设计模式:建造者模式(Builder Pattern) - 简书

https://refactoringguru.cn/design-patterns/builder

项目经验

风机:{变流器(型号:445)、适配器(型号:d200)、散热器(水冷)}

太阳能:{变流器(型号:446)、适配器(型号:d100)、散热器(风冷)}

缺点:

遇见结构框架不一样的:

亚洲人:{身高()、体重()、肤色()、发色()}

非洲人:{身高()、体重()、肤色()、发色()}

欧洲人:{身高()、体重()、肤色()、发色()}

猴子:{身高(、体重()、毛色()、尾巴长度()}

Carson带你学设计模式:建造者模式(Builder Pattern) - 简书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值