Eine kurze Diskussion über die Implementierung des Beobachtermusters in C++

Warum gibt es das Beobachtermuster?

Stellen Sie sich eine Szene mit einer Katze und einer Gruppe Mäuse vor. Wenn die Katze erscheint, müssen alle Mäuse weglaufen.

Verwenden Sie die einfachste Methode, um diesen Prozess zu simulieren

#include<iostream>

class Mouse_1
{
	public:
		void CatCome()
		{
			std::cout<<"Mouse_1 Run"<<std::endl;	
		}
};

class Mouse_2
{
	public:
		void CatCome()
		{
			std::cout<<"Mouse_2 Run"<<std::endl;	
		}
};

class Cat
{
	public:
		void IamCome()
		{
			std::cout<<"Cat Come!!!"<<std::endl;	
			mouse_1.CatCome();
			mouse_2.CatCome();
		}
	private:
		Mouse_1 mouse_1;
		Mouse_2 mouse_2;
};

int main()
{
	Cat cat;
	cat.IamCome();
	return 0;
}

Nach der Ausführung:

 Wenn Sie es so schreiben und eine weitere Maus hinzufügen möchten, müssen Sie die Katzenklasse in ändern

class Cat
{
	public:
		void IamCome()
		{
			std::cout<<"Cat Come!!!"<<std::endl;	
			mouse_1.CatCome();
			mouse_2.CatCome();
			mouse_3.CatCome();
		}
	private:
		Mouse_1 mouse_1;
		Mouse_2 mouse_2;
		Mouse_3 mouse_3;
};

In diesem Fall müssen Sie die Cat-Klasse jedes Mal ändern, was nicht sehr praktisch ist. Gibt es also einen Modus, der die Funktion des Hinzufügens einer Maus implementieren kann, ohne diese Klasse zu ändern? Dann gibt es den Beobachtermodus.

Implementierung des Beobachtermusters

Zuerst müssen wir eine Schnittstelle definieren, die alle Mäuse erben:

class MosueInterface
{
	public:
		virtual void CatCome()=0;
		virtual ~MosueInterface(){}
};

Dann definieren Sie zwei „Mäuse“:

class Mouse_1 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_1 Run"<<std::endl;	
		}
};

class Mouse_2 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_2 Run"<<std::endl;	
		}
};

Als nächstes müssen wir die alte Katze definieren. Zuerst benötigen wir einen Vektor, um alle Mäuse zu speichern:

std::vector<MosueInterface*> mice;

Definieren Sie die Methode zum Hinzufügen und Ändern dieses Vektors in der Laomao-Methode:

//向vector中添加老鼠
void Add(MosueInterface* mouse) 
{
	mice.push_back(mouse);
}
//从vector中删除老鼠
void Remove(MosueInterface* mouse) 
{
	std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
	if(it!=mice.end())
	{
		mice.erase(it);
	}
}

Durchqueren Sie den Vektor und senden Sie nacheinander die Nachricht „Ich komme“ an die Mäuse:

void IamCome() 
{
	std::cout<<"Cat Come!!!"<<std::endl;	
	for(const auto i : mice)
		{
			i->CatCome();
		}
}

Die allgemeine Definition einer alten Katze lautet wie folgt: 

class Cat 
{
	public:
		void Add(MosueInterface* mouse) 
		{
			mice.push_back(mouse);
		}
		
		void Remove(MosueInterface* mouse) 
		{
			std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
			if(it!=mice.end())
			{
				mice.erase(it);
			}
		}
		void IamCome() 
		{
			std::cout<<"Cat Come!!!"<<std::endl;	
			for(const auto i : mice)
			{
				i->CatCome();
			}
		}
	private:
		std::vector<MosueInterface*> mice;
};

Ereignisse in main ausführen:

int main()
{
	Cat cat;
	cat.Add(new Mouse_1);
	cat.Add(new Mouse_2);
	cat.IamCome();
	return 0;
}

Der Gesamtcode lautet wie folgt

#include<iostream>
#include<vector>
#include<algorithm>

class MosueInterface
{
	public:
		virtual void CatCome()=0;
		virtual ~MosueInterface(){}
};


class Mouse_1 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_1 Run"<<std::endl;	
		}
};

class Mouse_2 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_2 Run"<<std::endl;	
		}
};

class Cat 
{
	public:
		//向vector中添加老鼠
		void Add(MosueInterface* mouse) 
		{
			mice.push_back(mouse);
		}
		//从vector中删除老鼠
		void Remove(MosueInterface* mouse) 
		{
			std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
			if(it!=mice.end())
			{
				mice.erase(it);
			}
		}
		void IamCome() 
		{
			std::cout<<"Cat Come!!!"<<std::endl;	
			for(const auto i : mice)
			{
				i->CatCome();
			}
		}
	private:
		std::vector<MosueInterface*> mice;
};

int main()
{
	Cat cat;
	cat.Add(new Mouse_1);
	cat.Add(new Mouse_2);
	cat.IamCome();
	return 0;
}

Nach der Ausführung:

 Zu diesem Zeitpunkt fungiert die Katze als Beobachter und die Maus als Beobachter. Zu diesem Zeitpunkt, wenn das Ereignis „Ich bin hier“ ausgeführt wird, ist es nicht erforderlich, den ausgeführten Code jedes Mal zu ändern. Sie müssen es nur tun Fügen Sie es in die Hauptfunktion ein.

Abstrahieren Sie den Code

Zu diesem Zeitpunkt möchten wir den Beobachter und das Beobachtete abstrahieren. Der Code lautet wie folgt:

#include<iostream>
#include<vector>
#include<algorithm>

class MosueInterface
{
	public:
		virtual void CatCome()=0;
		virtual ~MosueInterface(){}
};

class CatInterface{
public:
    virtual void Add(MosueInterface* mouse)=0;
    virtual void Remove(MosueInterface* mouse)=0;
    virtual void IamCome()=0;
    virtual ~CatInterface(){}
};

class Mouse_1 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_1 Run"<<std::endl;	
		}
};

class Mouse_2 : public MosueInterface
{
	public:
		void CatCome() override
		{
			std::cout<<"Mouse_2 Run"<<std::endl;	
		}
};

class Cat : public CatInterface
{
	public:
		void Add(MosueInterface* mouse) override
		{
			mice.push_back(mouse);
		}
		
		void Remove(MosueInterface* mouse) override
		{
			std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
			if(it!=mice.end())
			{
				mice.erase(it);
			}
		}
		void IamCome() override
		{
			std::cout<<"Cat Come!!!"<<std::endl;	
			for(const auto i : mice)
			{
				i->CatCome();
			}
		}
	private:
		std::vector<MosueInterface*> mice;
};

int main()
{
	Cat cat;
	cat.Add(new Mouse_1);
	cat.Add(new Mouse_2);
	cat.IamCome();
	return 0;
}

In vielen Designs sind mehrere Objekte häufig an Datenänderungen in einem speziellen Objekt interessiert, und diese mehreren Objekte möchten Datenänderungen in diesem speziellen Objekt verfolgen. Das heißt, wenn zwischen Objekten eine Eins-zu-Viele-Beziehung besteht In solchen Fällen kann das Beobachtermuster verwendet werden. Wenn ein Objekt geändert wird, werden seine abhängigen Objekte automatisch benachrichtigt.

Das Observer-Muster ist ein ausgereiftes Muster, bei dem mehrere Objekte die Datenänderungen in einem Objekt wissen möchten. Im Beobachtermuster gibt es ein Objekt namens „Thema“ und mehrere Objekte namens „Beobachter“. Zwischen „Thema“ und „Beobachtern“ besteht eine Eins-zu-Viele-Abhängigkeitsbeziehung. Wenn der Status von „Thema“ Bei einer Änderung auftritt, werden alle „Beobachter“ benachrichtigt.

Guess you like

Origin blog.csdn.net/qq_36653924/article/details/131578424