一、建造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
示例:
//房子(产品类)
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();}
};
测试代码:
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;
输出结果:
This house has:
3 rooms.
6 windows.
Simlpe modern style decoration.This house has:
8 rooms.
16 windows.
Luxury classic style decoration.
二、中介者模式
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
示例:
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;}
};
测试代码:
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;
输出结果:
房东:张阿姨 收到来自租客:李明 的消息:
我正在寻找公司附近预算有限的一居室。
租客:李明 收到来自房东:张阿姨 的消息:
我有一套商业区附近的一居室可出租。
三、备忘录模式
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将对象恢复到原先保存的状态。
示例:
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];}
};
测试代码:
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();
输出结果:
Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2Level: 2
Hp: 120
Mp: 60
Equipment: sword shield
Quest Progress: 1Level: 3
Hp: 90
Mp: 70
Equipment: sword shield armour
Quest Progress: 2