《设计模式的艺术》笔记 - 建造者模式

介绍

建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造这模式是一种对象创建型模式。

实现

myclass.h

cpp 复制代码
//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>

class Product {

};

class Builder {
public:
    virtual void buildPartA() = 0;
    virtual void buildPartB() = 0;
    virtual void buildPartC() = 0;

    virtual Product *getResult();

protected:
    Product *m_product;
};

class ConcreteBuilder : public Builder {    // 具体建造者,负责产品的具体建造过程
public:
    void buildPartA() override;
    void buildPartB() override;
    void buildPartC() override;
};

class Director {    // 指挥者,负责指挥建造者进行产品建造
public:
    Director(Builder *builder);

    Product *construct();
private:
    Builder *m_builder;
};

#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

cpp 复制代码
//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"

Product* Builder::getResult() {
    return m_product;
}

void ConcreteBuilder::buildPartA() {
    std::cout << "ConcreteBuilder构建A部分" << std::endl;
}

void ConcreteBuilder::buildPartB() {
    std::cout << "ConcreteBuilder构建B部分" << std::endl;
}

void ConcreteBuilder::buildPartC() {
    std::cout << "ConcreteBuilder构建C部分" << std::endl;
}

Director::Director(Builder *builder) {
    m_builder = builder;
}

Product* Director::construct() {
    if (m_builder) {
        m_builder->buildPartA();
        m_builder->buildPartC();
        m_builder->buildPartB();
        return m_builder->getResult();
    }
    return nullptr;
}

main.cpp

cpp 复制代码
#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    Builder *builder = new ConcreteBuilder();
    Director *director = new Director(builder);
    Product *product = director->construct();
    delete builder;
    delete director;
    delete product;

    return 0;
}

总结

优点:

  1. 在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。

  2. 每个具体建造者都相对独立,而与其他具体建造者无关。因此,可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对抽象建造者编程,增加新的具体建造者无须修改原有类库的代码,系统扩展方便,符合开闭原则。

  3. 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。

缺点:

  1. 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似。如果产品之间的差异性很大,例如很多组成部分都不相同,就不适合使用建造者模式,因此其使用范围受到一定的限制。

  2. 如果产品的内部结构复杂且多变,可能会需要定义很多具体建造者类来实现这种变化,这就导致系统变得很庞大,增加系统的理解难度和运行成本。

适用场景:

  1. 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员变量。

  2. 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。

  3. 对象的创建过程独立于创建该对象的类。在建造者模式中通过引入指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。

  4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

练习

myclass.h

cpp 复制代码
//
// Created by yuwp on 2024/1/12.
//

#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H

#include <iostream>

class VideoPlayer {
public:
    const std::string &getMMode() const;

    void setMMode(const std::string &mMode);

    bool isMIsShowMenu() const;

    void setMIsShowMenu(bool mIsShowMenu);

    bool isMIsPlayList() const;

    void setMIsPlayList(bool mIsPlayList);

    bool isMIsMainWindow() const;

    void setMIsMainWindow(bool mIsMainWindow);

    bool isMIsController() const;

    void setMIsController(bool mIsController);

    bool isMIsCollectList() const;

    void setMIsCollectList(bool mIsCollectList);

    void play();

private:
    std::string m_mode;
    bool m_isShowMenu;
    bool m_isPlayList;
    bool m_isMainWindow;
    bool m_isController;
    bool m_isCollectList;
};

class VideoPlayerBuilder {
public:
    VideoPlayerBuilder();
    ~VideoPlayerBuilder();
    virtual void buildMode() = 0;
    virtual void buildMenu() = 0;
    virtual void buildPlayList() = 0;
    virtual void buildMainWindow() = 0;
    virtual void buildController() = 0;
    virtual void buildCollectList() = 0;

    VideoPlayer *construct();

protected:
    VideoPlayer *m_player;
};

class CompletePlayerBuiler : public VideoPlayerBuilder {
public:
    void buildMode() override;

    void buildMenu() override;

    void buildPlayList() override;

    void buildMainWindow() override;

    void buildController() override;

    void buildCollectList() override;
};

class SimplePlayerBuilder : public VideoPlayerBuilder {
public:
    void buildMode() override;

    void buildMenu() override;

    void buildPlayList() override;

    void buildMainWindow() override;

    void buildController() override;

    void buildCollectList() override;
};

class MemoryPlayerBuilder : public VideoPlayerBuilder {
public:
    void buildMode() override;

    void buildMenu() override;

    void buildPlayList() override;

    void buildMainWindow() override;

    void buildController() override;

    void buildCollectList() override;
};

#endif //DESIGNPATTERNS_MYCLASS_H

myclass.cpp

cpp 复制代码
//
// Created by yuwp on 2024/1/12.
//

#include "myclass.h"

const std::string &VideoPlayer::getMMode() const {
    return m_mode;
}

void VideoPlayer::setMMode(const std::string &mMode) {
    m_mode = mMode;
}

bool VideoPlayer::isMIsShowMenu() const {
    return m_isShowMenu;
}

void VideoPlayer::setMIsShowMenu(bool mIsShowMenu) {
    m_isShowMenu = mIsShowMenu;
}

bool VideoPlayer::isMIsPlayList() const {
    return m_isPlayList;
}

void VideoPlayer::setMIsPlayList(bool mIsPlayList) {
    m_isPlayList = mIsPlayList;
}

bool VideoPlayer::isMIsMainWindow() const {
    return m_isMainWindow;
}

void VideoPlayer::setMIsMainWindow(bool mIsMainWindow) {
    m_isMainWindow = mIsMainWindow;
}

bool VideoPlayer::isMIsController() const {
    return m_isController;
}

void VideoPlayer::setMIsController(bool mIsController) {
    m_isController = mIsController;
}

bool VideoPlayer::isMIsCollectList() const {
    return m_isCollectList;
}

void VideoPlayer::setMIsCollectList(bool mIsCollectList) {
    m_isCollectList = mIsCollectList;
}

void VideoPlayer::play() {
    std::cout << "------ " << getMMode() << " ------" << std::endl;
    if (m_isShowMenu) {
        std::cout << "显示菜单" << std::endl;
    }
    if (m_isPlayList) {
        std::cout << "显示播放列表" << std::endl;
    }
    if (m_isMainWindow) {
        std::cout << "显示主窗口" << std::endl;
    }
    if (m_isController) {
        std::cout << "显示控制条" << std::endl;
    }
    if (m_isCollectList) {
        std::cout << "显示收藏列表" << std::endl;
    }
}

VideoPlayerBuilder::VideoPlayerBuilder() {
    m_player = new VideoPlayer();
}

VideoPlayerBuilder::~VideoPlayerBuilder() {
    if (m_player) {
        delete m_player;
    }
}

VideoPlayer* VideoPlayerBuilder::construct() {
    buildMode();
    buildMenu();
    buildPlayList();
    buildMainWindow();
    buildController();
    buildCollectList();
    return m_player;
}

void CompletePlayerBuiler::buildMode() {
    m_player->setMMode("完整模式");
}

void CompletePlayerBuiler::buildMenu() {
    m_player->setMIsShowMenu(true);
}

void CompletePlayerBuiler::buildPlayList() {
    m_player->setMIsPlayList(true);
}

void CompletePlayerBuiler::buildMainWindow() {
    m_player->setMIsMainWindow(true);
}

void CompletePlayerBuiler::buildController() {
    m_player->setMIsController(true);
}

void CompletePlayerBuiler::buildCollectList() {
    m_player->setMIsCollectList(false);
}

void SimplePlayerBuilder::buildMode() {
    m_player->setMMode("精简模式");
}

void SimplePlayerBuilder::buildMenu() {
    m_player->setMIsShowMenu(false);
}

void SimplePlayerBuilder::buildPlayList() {
    m_player->setMIsPlayList(false);
}

void SimplePlayerBuilder::buildMainWindow() {
    m_player->setMIsMainWindow(true);
}

void SimplePlayerBuilder::buildController() {
    m_player->setMIsController(true);
}

void SimplePlayerBuilder::buildCollectList() {
    m_player->setMIsCollectList(false);
}

void MemoryPlayerBuilder::buildMode() {
    m_player->setMMode("记忆模式");
}

void MemoryPlayerBuilder::buildMenu() {
    m_player->setMIsShowMenu(false);
}

void MemoryPlayerBuilder::buildPlayList() {
    m_player->setMIsPlayList(false);
}

void MemoryPlayerBuilder::buildMainWindow() {
    m_player->setMIsMainWindow(true);
}

void MemoryPlayerBuilder::buildController() {
    m_player->setMIsController(true);
}

void MemoryPlayerBuilder::buildCollectList() {
    m_player->setMIsCollectList(true);
}

main.cpp

cpp 复制代码
#include <iostream>
#include <mutex>
#include "myclass.h"

int main() {
    VideoPlayerBuilder *builder = new CompletePlayerBuiler();
    VideoPlayer *player = builder->construct();
    player->play();
    delete builder;

    builder = new SimplePlayerBuilder();
    player = builder->construct();
    player->play();
    delete builder;

    builder = new MemoryPlayerBuilder();
    player = builder->construct();
    player->play();
    delete builder;

    return 0;
}
相关推荐
丝斯20116 小时前
AI学习笔记整理(42)——NLP之大规模预训练模型Transformer
人工智能·笔记·学习
凉、介8 小时前
深入 QEMU Guest Agent:虚拟机内外通信的隐形纽带
c语言·笔记·学习·嵌入式·虚拟化
GISer_Jing8 小时前
AI Agent 目标设定与异常处理
人工智能·设计模式·aigc
njsgcs8 小时前
SIMA2 论文阅读 Google 任务设定器、智能体、奖励模型
人工智能·笔记
蔺太微9 小时前
组合模式(Composite Pattern)
设计模式·组合模式
云半S一9 小时前
pytest的学习过程
经验分享·笔记·学习·pytest
AI视觉网奇9 小时前
ue5.7 配置 audio2face
笔记·ue5
鱼跃鹰飞10 小时前
DDD中的防腐层
java·设计模式·架构
会员果汁12 小时前
15.设计模式-组合模式
设计模式·组合模式
崎岖Qiu12 小时前
【OS笔记35】:文件系统的使用、实现与管理
笔记·操作系统·存储管理·文件系统·os