Una breve discusión sobre la implementación del patrón de observador en C++

¿Por qué tener el patrón de observador?

Imaginemos una escena con un gato y un grupo de ratones: cuando aparece el gato, todos los ratones tienen que huir.

Utilice el método más simple para implementar uno para simular este proceso.

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

Después de la ejecución:

 Si lo escribes así, si quieres agregar un mouse más, entonces debes cambiar la clase cat a

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

En este caso, tienes que modificar la clase Cat cada vez que la modificas, lo cual no es muy conveniente. Entonces, ¿existe un modo que pueda implementar la función de agregar un mouse sin modificar esta clase? Luego está el modo observador.

Implementación del patrón de observador.

Primero necesitamos definir una interfaz que hereden todos los ratones:

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

Luego define dos "ratones":

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

A continuación, necesitamos definir el gato viejo. Primero, necesitamos un vector para almacenar todos los ratones:

std::vector<MosueInterface*> mice;

Defina el método para agregar y modificar este vector en el método de Laomao:

//向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);
	}
}

Recorre el vector y envía el "mensaje Ya voy" a los ratones uno por uno:

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

La definición general de gato viejo es la siguiente: 

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

Ejecutar eventos en main:

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

El código general es el siguiente.

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

Después de la ejecución:

 En este momento, el gato actúa como observador y el ratón actúa como observador. En este momento, cuando se ejecuta el evento "Estoy aquí", no es necesario modificar el código ejecutado cada vez, solo necesita agréguelo en la función principal.

abstraer el código

En este momento queremos abstraer al observador y lo observado, el código es el siguiente:

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

En muchos diseños, varios objetos a menudo están interesados ​​en los cambios de datos en un objeto especial, y estos múltiples objetos quieren rastrear los cambios de datos en ese objeto especial, es decir, cuando existe una relación de uno a muchos entre objetos, en En tales casos se puede utilizar el patrón de observador. Cuando se modifica un objeto, sus objetos dependientes son notificados automáticamente.

El patrón Observer es un patrón maduro en el que varios objetos quieren conocer los cambios en los datos de un objeto. En el patrón de observador, hay un objeto llamado "tema" y varios objetos llamados "observadores". Existe una relación de dependencia de uno a muchos entre "tema" y "observadores". Cuando el estado del "tema" Cuando un cambio ocurre, se notifica a todos los "observadores".

Supongo que te gusta

Origin blog.csdn.net/qq_36653924/article/details/131578424
Recomendado
Clasificación