C++设计模式(建造者、中介者、备忘录)

一、建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

示例:

cpp 复制代码
//房子(产品类)
class House {
private:
    int rooms;
    int windows;
    string decoration;
public:
    void setRooms(int r) {
        rooms = r;
    }
    void setWindows(int w) {
        windows = w;
    }
    void setDecoration(const string& d) {
        decoration = d;
    }
    void show() {
        cout << "This house has:" << endl;
        cout << rooms << " rooms." << endl;
        cout << windows << " windows." << endl;
        cout << decoration << " decoration.\n" << endl;
    }
};

//抽象构建器
class HouseBuilder {
protected:
    House* house;
public:
    HouseBuilder() :house(new House()) {}
    ~HouseBuilder() {
        delete house;
    }
    virtual void buildRooms() = 0;
    virtual void buildWindows() = 0;
    virtual void buildDecoration() = 0;
    House* getHouse() const {
        return house;
    }
};

//公寓构建器(具体构件器)
class ApartmentBuilder :public HouseBuilder {
public:
    using HouseBuilder::HouseBuilder;
    virtual void buildRooms() override {
        house->setRooms(3);
    }
    virtual void buildWindows() override {
        house->setWindows(6);
    }
    virtual void buildDecoration() override {
        house->setDecoration("Simlpe modern style");
    }
};

//别墅构建器(具体构件器)
class VillaBuilder :public HouseBuilder {
public:
    using HouseBuilder::HouseBuilder;
    virtual void buildRooms() override {
        house->setRooms(8);
    }
    virtual void buildWindows() override {
        house->setWindows(16);
    }
    virtual void buildDecoration() override {
        house->setDecoration("Luxury classic style");
    }
};

//指导者
class Architect {
private:
    HouseBuilder* builder;
public:
    Architect(HouseBuilder* b) :builder(b) {}
    House* consruct() {
        builder->buildRooms();
        builder->buildWindows();
        builder->buildDecoration();
        return builder->getHouse();
    }
};

测试代码:

cpp 复制代码
HouseBuilder* builder1 = new ApartmentBuilder();
Architect* architect1 = new Architect(builder1);
House* apartment = architect1->consruct();
apartment->show();
delete builder1;
delete architect1;

HouseBuilder* builder2 = new VillaBuilder();
Architect* architect2 = new Architect(builder2);
House* villa = architect2->consruct();
villa->show();
delete builder2;
delete architect2;

输出结果:

bash 复制代码
This house has:
3 rooms.
6 windows.
Simlpe modern style decoration.

This house has:
8 rooms.
16 windows.
Luxury classic style decoration.

二、中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

示例:

cpp 复制代码
class Person;

//抽象中介者
class Mediator {
public:
    virtual void sendMsg(Person* p, string msg) = 0;
    virtual ~Mediator() {}
};

//抽象同事类
class Person {
protected:
    string name;
    Mediator* mediator;
public:
    Person(string n, Mediator* m) :name(n), mediator(m) {}
    virtual ~Person() {}
    virtual string getName() const = 0;
    virtual void receive(Person* p, string msg) = 0;
    void send(string msg) {
        mediator->sendMsg(this, msg);
    }
};

//房屋中介(具体中介者)
class HouseMediator :public Mediator {
private:
    Person* tenant;
    Person* landlord;
public:
    void setTenant(Person* t) {
        tenant = t;
    }
    void setLandlord(Person* l) {
        landlord = l;
    }
    virtual void sendMsg(Person* p, string msg) {
        if (p == tenant) {
            landlord->receive(p, msg);
        }
        else {
            tenant->receive(p, msg);
        }
    }
};

//租客(具体同事类)
class Tenant :public Person {
public:
    using Person::Person;
    void receive(Person* p, string msg) override {
        cout << "租客:" << name << " 收到来自房东:";
        cout << p->getName() << " 的消息:" << endl << msg << endl;
    }
    virtual string getName() const override {
        return name;
    }
};

//房东(具体同事类)
class Landlord :public Person {
public:
    using Person::Person;
    void receive(Person* p, string msg) override {
        cout << "房东:" << name << " 收到来自租客:";
        cout << p->getName() << " 的消息:" << endl << msg << endl;
    }
    virtual string getName() const override {
        return name;
    }
};

测试代码:

cpp 复制代码
HouseMediator* mediator = new HouseMediator();
Person* tenant1 = new Tenant("李明", mediator);
Person* landlord1 = new Landlord("张阿姨", mediator);
mediator->setTenant(tenant1);
mediator->setLandlord(landlord1);
tenant1->send("我正在寻找公司附近预算有限的一居室。");
landlord1->send("我有一套商业区附近的一居室可出租。");
delete mediator;
delete tenant1;
delete landlord1;

输出结果:

bash 复制代码
房东:张阿姨 收到来自租客:李明 的消息:
我正在寻找公司附近预算有限的一居室。
租客:李明 收到来自房东:张阿姨 的消息:
我有一套商业区附近的一居室可出租。

三、备忘录模式

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将对象恢复到原先保存的状态。

示例:

cpp 复制代码
struct CharacterState {
    int level;
    int hp;
    int mp;
    vector<string> equipment;
    int questProgress;
};

//备忘录类(用于存储游戏角色状态)
class GameMemento {
private:
    CharacterState m;
public:
    GameMemento(int le, int hp, int mp, const vector<string>& eq, int qp) {
        m = { le, hp, mp, eq, qp };
    }
    int getLevel() const {
        return m.level;
    }
    int getHp() const {
        return m.hp;
    }
    int getMp() const {
        return m.mp;
    }
    const vector<string>& getEquipment() const {
        return m.equipment;
    }
    int getQuestProgress() const {
        return m.questProgress;
    }
};

//游戏角色类(原发器)
class GameCharacter {
private:
    CharacterState m;
public:
    GameCharacter() {
        m = { 1, 100, 50,{"sword" }, 0 };
    }
    shared_ptr<GameMemento> save() const {
        return make_shared<GameMemento>
            (m.level, m.hp, m.mp, m.equipment, m.questProgress);
    }
    void restore(const shared_ptr<GameMemento>& memento) {
        m.level = memento->getLevel();
        m.hp = memento->getHp();
        m.mp = memento->getMp();
        m.equipment = memento->getEquipment();
        m.questProgress = memento->getQuestProgress();
    }
    void LevelUp() {
        m.level++;
        m.hp += 20;
        m.mp += 10;
    }
    void getHurt(int damage) {
        m.hp -= damage;
        if (m.hp < 0)
            m.hp = 0;
    }
    void addEquipment(const string& item) {
        m.equipment.emplace_back(item);
    }
    void completeQuest() {
        m.questProgress++;
    }
    void showStatus() const {
        cout << "Level: " << m.level << endl;
        cout << "Hp: " << m.hp << endl;
        cout << "Mp: " << m.mp << endl;
        cout << "Equipment: ";
        for (const auto& item : m.equipment) {
            cout << item << " ";
        }
        cout << endl;
        cout << "Quest Progress: " << m.questProgress << endl << endl;
    }
};

//存档管理类(管理者)
class SaveManager {
private:
    vector<shared_ptr<GameMemento>> saves;
public:
    void saveGame(const shared_ptr<GameMemento>& memento) {
        saves.emplace_back(memento);
    }
    const shared_ptr<GameMemento>& loadGame(int index) {
        if (index < 0 || index >= saves.size())
            return nullptr;
        return saves[index];
    }
};

测试代码:

cpp 复制代码
shared_ptr<GameCharacter> character = make_shared<GameCharacter>();
shared_ptr<SaveManager> manager = make_shared<SaveManager>();
character->LevelUp();
character->addEquipment("shield");
character->completeQuest();
character->showStatus();
manager->saveGame(character->save());

character->LevelUp();
character->getHurt(50);
character->addEquipment("armour");
character->completeQuest();
character->showStatus();
manager->saveGame(character->save());

character->restore(manager->loadGame(0));
character->showStatus();
character->restore(manager->loadGame(1));
character->showStatus();

输出结果:

bash 复制代码
Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1

Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2

Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1

Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2
相关推荐
王老师青少年编程3 小时前
gesp(C++五级)(14)洛谷:B4071:[GESP202412 五级] 武器强化
开发语言·c++·算法·gesp·csp·信奥赛
DogDaoDao3 小时前
leetcode 面试经典 150 题:有效的括号
c++·算法·leetcode·面试··stack·有效的括号
一只小bit4 小时前
C++之初识模版
开发语言·c++
CodeClimb5 小时前
【华为OD-E卷 - 第k个排列 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
等一场春雨5 小时前
Java设计模式 九 桥接模式 (Bridge Pattern)
java·设计模式·桥接模式
apz_end6 小时前
埃氏算法C++实现: 快速输出质数( 素数 )
开发语言·c++·算法·埃氏算法
仟濹6 小时前
【贪心算法】洛谷P1106 - 删数问题
c语言·c++·算法·贪心算法
北顾南栀倾寒7 小时前
[Qt]系统相关-网络编程-TCP、UDP、HTTP协议
开发语言·网络·c++·qt·tcp/ip·http·udp
old_power8 小时前
【PCL】Segmentation 模块—— 基于图割算法的点云分割(Min-Cut Based Segmentation)
c++·算法·计算机视觉·3d
涛ing8 小时前
21. C语言 `typedef`:类型重命名
linux·c语言·开发语言·c++·vscode·算法·visual studio