【设计模式学习笔记】中介者模式、观察者模式、备忘录模式案例详解(C++实现)
目录
一、中介者模式
1. 什么是中介者模式
Mediator Pattern,中介者模式,行为型模式之一。类与类之间的交互都放在一个中介对象中进行,即类通过中介和另一个类交互,类与类之间不用互相引用就能实现交互,降低了类与类之间的耦合。但是需要通过中介者进行交互的类中包含了中介者的引用,而中介者也包含了所有需要交互的类的引用。举例来说,比如男女相亲,男生女生之间互不相识(交互双方不需互相引用),但是他们都认识媒人(交互者包含了中介者的引用),而且没人也认识男生和女生(中介者包含了交互者的引用),再比如第三方招聘平台、招聘者、应聘者之间的关系也是这样。
- Mediator:抽象中介者,定义了同事对象到中介者对象的接口;
- ConcreteMediator:具体中介者,它包含了所有具体同事类的引用,并实现抽象中介类中的接口;
- Colleague:抽象同事类;
- ConcreteColleague:具体同事类,每个同事类只知道自己的行为,但是他们都包含中介类的引用(都认识中介);
2.中介者模式案例
大学生通过BOOS直聘找工作,那么大学生和HR就需要通过BOOS直聘找工作,BOOS直聘就是中介,首先定义一个抽象中介类。
class Mediator //抽象中介者
{
public:
virtual void match() = 0;
virtual void set_hr(Role* hr) = 0;
virtual void set_student(Role* student) = 0;
};
定义具体的中介BOOS直聘,大学生和公司HR通过BOOS直聘求职或招聘。
class Boos : public Mediator //BOOS直聘平台
{
private:
Role* hr;
Role* student;
public:
virtual void set_hr(Role* hr)
{
this->hr = hr;
}
virtual void set_student(Role* student)
{
this->student = student;
}
virtual void match()
{
cout << "=========================" << endl;
cout << hr->get_name() << " 提供职位:" << hr->get_office() << endl;
cout << student->get_name() << " 需求职位:" << student->get_office() << endl;
if (hr->get_office() == student->get_office())
{
cout << "***匹配成功***" << endl;
}
else
{
cout << "***匹配失败***" << endl;
}
cout << "=========================" << endl;
}
};
定义抽象同事类,也就是需要交互的类,他应该包含一个中介类的引用,因为大学生和HR都应该认识BOOS直聘平台。
class Role //抽象角色
{
protected:
string name;
string office;
Mediator* mediator;
public:
Role(string name, string office, Mediator* mediator)
{
this->name = name;
this->office = office;
this->mediator = mediator;
}
string get_name()
{
return this->name;
}
string get_office()
{
return this->office;
}
virtual void match(Role* role) = 0;
};
定义学生类和HR类
class Student : public Role
{
public:
Student(string name, string office, Mediator* mediator) : Role(name, office, mediator) {};
virtual void match(Role* role)
{
mediator->set_hr(role);
mediator->set_student(this);
mediator->match();
}
};
class HR : public Role
{
public:
HR(string name, string office, Mediator* mediator) : Role(name, office, mediator) {};
virtual void match(Role* role)
{
mediator->set_hr(this);
mediator->set_student(role);
mediator->match();
}
};
大学生和HR通过BOOS进行交互
int main()
{
Role* hr = NULL;
Role* stu1 = NULL, * stu2 = NULL;
Mediator* medi = NULL;
medi = new Boos;
hr = new HR("七总", "C++", medi);
stu1 = new Student("小明", "Java", medi);
stu2 = new Student("小红", "C++", medi);
hr->match(stu1);
hr->match(stu2);
delete stu2;
delete stu1;
delete hr;
system("pause");
return 0;
}
二、观察者模式
1. 什么是观察者模式
Observer Pattern,观察者模式,行为型模式之一。观察者模式提供了一种一对多的模式,多个观察者对象同时监听一个主题对象,一旦主题对象发生变化,能够自动通知所有的观察者对象。它提供了一种关联对象之间的同步机制,他们之间通过通信来保持状态同步。
- Subject:抽象主题角色,被观察的对象,当被观察的状态发生变化时,会通知所有的观察者,Subject一般包含了所有观察者对象的引用(集合);
- ConcreteSubject:具体主题,被观察者的具体实现,当状态发生改变时,向所有观察者发出通知;
- Observer:抽象观察者,提供统一的接口,在得到通知时执行某些操作;
- ConcreteObserver:具体观察者,实现抽象观察者提供的接口;
2. 观察者模式案例
假设两军作战,观察者为士兵
//观察者
class Soldier //士兵
{
private:
Guard* guard;
public:
Soldier(Guard* guard)
{
this->guard = guard;
}
void recv_infor(string infor)
{
cout << infor << ": 收到, 准备战斗" << endl;
}
};
被观察者为哨兵,一旦发现敌军,则通知所有士兵,被观察者含有一个观察者类型的容器,用于保存所有观察者的引用。
class Guard //哨兵
{
private:
list<Soldier*> l;
public:
void add_observer(Soldier* soldier)
{
l.push_back(soldier);
}
void send_infor(string infor)
{
for (list<Soldier*>::iterator it = l.begin(); it != l.end(); it++)
{
(*it)->recv_infor(infor);
}
}
};
士兵收到通知,进行统一的行动,假设军队总共三个士兵
int main()
{
Soldier* s1 = NULL, * s2 = NULL, * s3 = NULL;
Guard* g = NULL;
g = new Guard;
s1 = new Soldier(g);
s2 = new Soldier(g);
s3 = new Soldier(g);
g->add_observer(s1);
g->add_observer(s2);
g->add_observer(s3);
string s = "敌人来了";
g->send_infor(s);
system("pause");
return 0;
}
三、备忘录模式
1. 什么是备忘录模式
Memento Pattern,备忘录模式,行为型模式之一。备忘录模式在不破坏封装性的前提下,捕获一个对象的内部状态,并在外部保存,并在需要的时候恢复对象以前的状态。可以理解为,在备忘录中保存了一个对象的备份,当对象已经发生了改变,并且我们需要恢复对象以前的状态时,可以通过一个备忘录管理器来恢复以前的状态。
- Originator:原生者角色,需要在备忘录中保存的对象,负责创建一个备忘录,并进行保存和恢复状态的操作;
- Memento:备忘录,用于保存Originator的内部状态;
- Caretaker:管理者,包含一个备忘录的引用,负责操作和管理备忘录;
2. 备忘录模式案例
定义一个备忘录
class Memento //备忘录
{
private:
string str;
public:
Memento(string str)
{
this->str = str;
}
string get_str()
{
return this->str;
}
};
定义一个原生者
class Originator
{
private:
string str;
public:
void set_str(string str)
{
this->str = str;
}
Memento* get_memo()
{
return new Memento(this->str);
}
void print_str()
{
cout << this->str << endl;
}
void recover(Memento* memo)
{
this->str = memo->get_str();
}
};
定义一个管理者
class Caretaker
{
private:
Memento* memo;
public:
void set_memo(Memento* memo)
{
this->memo = memo;
}
Memento* get_memo()
{
return this->memo;
}
};
客户端测试,修改一个对象属性,并通过备忘录恢复状态
int main()
{
Originator* ori = NULL;
Caretaker* care = NULL;
care = new Caretaker;
//原始状态
ori = new Originator;
ori->set_str("原始状态");
ori->print_str();
care->set_memo(ori->get_memo());
//修改状态
ori->set_str("状态改变");
ori->print_str();
//恢复状态
ori->recover(care->get_memo());
ori->print_str();
delete care;
delete ori;
system("pause");
return 0;
}