建造者模式详解:原理及示例代码、结构图、使用场景及优缺点

前言:

        继续来聊一聊创建型设计模式:建造者模式;

前面还有聊过一些其他创建型模式,传送门如下:

工厂模式C++示例代码:简单工厂模式、工厂方法模式和抽象工厂模式-CSDN博客

工厂模式:抽象工厂模式 C++代码实现、场景及优缺点-CSDN博客 

工厂模式:简单工厂知多少?原理、示例代码、场景及优缺点?-CSDN博客 

设计模式:C++如何实现一个高质量的单例模式,双重校验锁 懒汉多线程安全 ,还得考虑防止编译器优化、异常死锁-CSDN博客

一、建造者模式原理及示例代码 

        建造者模式是一种创建型设计模式,它用于创建复杂对象。该模式允许您逐步构造一个对象,同时隐藏构造细节。这种模式特别适用于创建具有多个属性的对象,或者创建过程中涉及多个步骤的对象。

建造者模式通常由以下几个角色组成:

  1. 产品(Product):要创建的复杂对象。
  2. 抽象建造者(Builder):定义了创建产品各个部件的抽象接口。
  3. 具体建造者(ConcreteBuilder):实现了抽象建造者接口,负责具体的产品部件的创建。
  4. 指挥者(Director):负责使用建造者来构建产品对象。

下面是一个简单的C++源码实现建造者模式的示例:

#include <iostream>
#include <string>

// 产品类
class Pizza {
public:
    void setDough(const std::string& dough) {
        m_dough = dough;
    }
    void setSauce(const std::string& sauce) {
        m_sauce = sauce;
    }
    void setTopping(const std::string& topping) {
        m_topping = topping;
    }
    void open() const {
        std::cout << "Pizza with " << m_dough << " dough, " << m_sauce << " sauce and " << m_topping << " topping. Mmm!" << std::endl;
    }
private:
    std::string m_dough;
    std::string m_sauce;
    std::string m_topping;
};

// 抽象建造者
class PizzaBuilder {
public:
    virtual ~PizzaBuilder() {}
    Pizza* getPizza() {
        return m_pizza;
    }
    void createNewPizza() {
        m_pizza = new Pizza();
    }
    virtual void buildDough() = 0;
    virtual void buildSauce() = 0;
    virtual void buildTopping() = 0;
protected:
    Pizza* m_pizza;
};

// 具体建造者
class HawaiianPizzaBuilder : public PizzaBuilder {
public:
    virtual void buildDough() override {
        m_pizza->setDough("cross");
    }
    virtual void buildSauce() override {
        m_pizza->setSauce("mild");
    }
    virtual void buildTopping() override {
        m_pizza->setTopping("ham+pineapple");
    }
};

class SpicyPizzaBuilder : public PizzaBuilder {
public:
    virtual void buildDough() override {
        m_pizza->setDough("pan baked");
    }
    virtual void buildSauce() override {
        m_pizza->setSauce("hot");
    }
    virtual void buildTopping() override {
        m_pizza->setTopping("pepperoni+salami");
    }
};

// 指挥者
class Cook {
public:
    void setPizzaBuilder(PizzaBuilder* pb) {
        m_pizzaBuilder = pb;
    }
    Pizza* getPizza() {
        return m_pizzaBuilder->getPizza();
    }
    void constructPizza() {
        m_pizzaBuilder->createNewPizza();
        m_pizzaBuilder->buildDough();
        m_pizzaBuilder->buildSauce();
        m_pizzaBuilder->buildTopping();
    }
private:
    PizzaBuilder* m_pizzaBuilder;
};

int main() {
    Cook cook;
    HawaiianPizzaBuilder hawaiianPizzaBuilder;
    SpicyPizzaBuilder spicyPizzaBuilder;

    cook.setPizzaBuilder(&hawaiianPizzaBuilder);
    cook.constructPizza();

    Pizza* hawaiianPizza = cook.getPizza();
    hawaiianPizza->open();

    cook.setPizzaBuilder(&spicyPizzaBuilder);
    cook.constructPizza();

    Pizza* spicyPizza = cook.getPizza();
    spicyPizza->open();

    delete hawaiianPizza;
    delete spicyPizza;

    return 0;
}

在这个示例中,Pizza类是产品类,PizzaBuilder是抽象建造者,HawaiianPizzaBuilderSpicyPizzaBuilder是具体建造者,Cook是指挥者。通过使用建造者模式,我们可以逐步构建不同类型的披萨对象,而不需要了解具体的构建细节。

 

二、结构图

        建造者模式的结构图通常包括以下几个要素:

  1. 产品(Product):要创建的复杂对象。
  2. 抽象建造者(Builder):定义了创建产品各个部件的抽象接口。
  3. 具体建造者(ConcreteBuilder):实现了抽象建造者接口,负责具体的产品部件的创建。
  4. 指挥者(Director):负责使用建造者来构建产品对象。

下面是建造者模式的结构图示例:

+-------------------+              +------------------+
|      Product      |              |    Builder       |
+-------------------+              +------------------+
|                   |              | + createProduct()|
|                   |              | + buildPartA()   |
|                   |              | + buildPartB()   |
|                   |              | + buildPartC()   |
+---------+---------+              +--------+---------+
          |                                  |
          |                                  |
          |                                  |
          |                                  |
+---------+---------+              +--------+---------+
|ConcreteProduct   |              | ConcreteBuilder |
+-------------------+              +------------------+
|                   |              | + buildPartA()   |
|                   |              | + buildPartB()   |
|                   |              | + buildPartC()   |
+-------------------+              +--------+---------+
                                                  |
                                                  |
                                                  |
                                                  |
                                          +-------+---------+
                                          |   Director    |
                                          +---------------+
                                          | + construct() |
                                          +---------------+

在这个结构图中,产品(Product)是要创建的复杂对象,抽象建造者(Builder)定义了创建产品各个部件的抽象接口。具体建造者(ConcreteBuilder)实现了抽象建造者接口,负责具体的产品部件的创建。指挥者(Director)负责使用建造者来构建产品对象。

 

三、使用场景

建造者模式通常适用于以下场景:

  1. 当创建复杂对象的构造过程需要独立于其表示时,可以使用建造者模式。这意味着构造过程可以有不同的表示,而客户端代码无需关心具体的构造细节。

  2. 当一个对象的构造过程具有多个步骤,并且不同的构造步骤可以产生不同的表示时,建造者模式是一个很好的选择。通过使用建造者模式,可以将构造过程的每个步骤进行解耦,以便可以灵活地组合这些步骤来构建不同的对象表示。

  3. 当需要创建的对象具有复杂的内部结构,但客户端代码只关心最终的产品对象时,建造者模式可以隐藏对象的内部构造细节,使客户端代码更加简洁。

  4. 当创建对象的过程中涉及到可选的部件时,可以使用建造者模式。建造者模式可以方便地处理可选部件的构造和组合,而不需要创建大量的构造方法重载。

总之,建造者模式适用于需要创建复杂对象,且希望将构造过程与表示分离的情况。它可以帮助我们更好地组织对象的构造过程,使得代码更加灵活、可维护和可扩展。

四:优缺点

 

建造者模式的优点包括:

  1. 分离构建过程和最终表示:建造者模式可以将一个复杂对象的构建过程与其最终表示分离开来,使得构建过程可以灵活地组合,而不会影响最终的产品表示。

  2. 容易扩展:由于建造者模式将构建过程解耦,因此可以比较容易地增加新的具体建造者,以及修改已有的具体建造者,而不会对客户端代码产生影响。

  3. 可以对构建过程进行精细控制:建造者模式允许您对构建过程的每个步骤进行精细的控制,从而可以更好地满足特定需求。

  4. 提高代码复用性:通过建造者模式,可以将构建过程的代码进行复用,从而避免了重复的构建代码,提高了代码的复用性。

建造者模式的缺点包括:

  1. 增加了系统的复杂度:引入了建造者模式后,系统会增加一些新的类,从而增加了系统的复杂度。

  2. 需要额外的开发工作:使用建造者模式需要定义抽象建造者、具体建造者等额外的类,这可能增加了一些额外的开发工作。

总的来说,建造者模式适用于需要构建复杂对象,且希望将构建过程与最终表示分离的情况。它可以提供灵活性、可扩展性和精细控制,但也需要权衡额外的复杂度和开发工作。

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五木大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值