一、建造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
示例:
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