【设计模式学习笔记】中介者模式、观察者模式、备忘录模式案例详解(C++实现)

目录

一、中介者模式

1. 什么是中介者模式

2.中介者模式案例

二、观察者模式

1. 什么是观察者模式

2. 观察者模式案例 

三、备忘录模式

1. 什么是备忘录模式

2. 备忘录模式案例


一、中介者模式

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;
}

posted @ 2022-04-22 11:15  Mindtechnist  阅读(7)  评论(0编辑  收藏  举报  来源