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

介绍

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

实现

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;
}
相关推荐
LateBloomer77714 分钟前
FreeRTOS——信号量
笔记·stm32·学习·freertos
legend_jz17 分钟前
【Linux】线程控制
linux·服务器·开发语言·c++·笔记·学习·学习方法
Komorebi.py18 分钟前
【Linux】-学习笔记04
linux·笔记·学习
fengbizhe1 小时前
笔试-笔记2
c++·笔记
余为民同志1 小时前
mini-lsm通关笔记Week2Day4
笔记
墨染风华不染尘1 小时前
python之开发笔记
开发语言·笔记·python
徐霞客3202 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt
澜世2 小时前
2024小迪安全基础入门第三课
网络·笔记·安全·网络安全
Bald Baby2 小时前
JWT的使用
java·笔记·学习·servlet
rellvera3 小时前
【强化学习的数学原理】第02课-贝尔曼公式-笔记
笔记·机器学习