设计模式-行为-Observer(观察者)模式

梦想游戏人
目录:
软件架构

典型的应用就是MVC模式

定义了一对多的关系,一个对象的改变,所依赖的其他对象都将获得通知并且更新。

场景1:看电视,喜欢看这个频道的 会选择看这个频道,

场景2:类似于订阅自己关心的状态,该状态的消息来了,那么就会得到通知

观察者模式缺点也很明显

1.每次都要广播筛选 合适的观察者

例1

  • 头文件
  • #include "PublicHeaders.h"
  • #include <vector>
  • #include <string>
  • class Observer;
  • class Subject
  • {
  • public:
  • virtual void Attach(Observer*) = 0;
  • virtual void Detach(Observer*) = 0;
  • virtual void Notify() = 0;
  • void setState(const std::string&state)
  • {
  • this->_state = state;
  • }
  • const std::string& getState()const
  • {
  • return _state;
  • }
  • private:
  • std::string _state;
  • protected:
  • std::vector<Observer*> _observers;
  • };
  • class ConCreateSubject :public Subject
  • {
  • public:
  • virtual void Attach(Observer*) override;
  • virtual void Detach(Observer*)override;
  • virtual void Notify() override;
  • };
  • class Observer
  • {
  • public:
  • virtual void Update(const std::string &state) = 0;
  • };
  • class ConCreateObserverA :public Observer
  • {
  • public:
  • virtual void Update(const std::string& state)override
  • {
  • if (state == "A")
  • {
  • cout << __FUNCTION__ << endl;
  • }
  • }
  • };
  • class ConCreateObserverB :public Observer
  • {
  • public:
  • virtual void Update(const std::string& state)override
  • {
  • if (state == "B")
  • {
  • cout << __FUNCTION__ << endl;
  • }
  • }
  • };
  • void testObserver();
  • 源文件
  • #include "Observer.h"
  • void ConCreateSubject::Attach(Observer*observer)
  • {
  • _observers.push_back(observer);
  • }
  • void ConCreateSubject::Detach(Observer*observer)
  • {
  • auto iter = std::find(_observers.begin(), _observers.end(), observer);
  • if (iter != _observers.end())
  • {
  • _observers.erase(iter);
  • }
  • }
  • void ConCreateSubject::Notify()
  • {
  • for (int i = 0; i < _observers.size(); ++i)
  • {
  • _observers[i]->Update(this->getState());
  • }
  • }
  • void testObserver()
  • {
  • ConCreateSubject *sub = new ConCreateSubject;
  • auto a1 = new ConCreateObserverA;
  • sub->Attach(a1);
  • auto a2 = new ConCreateObserverA;
  • sub->Attach(a2);
  • auto b1 = new ConCreateObserverB;
  • sub->Attach(b1);
  • sub->setState("A");
  • sub->Notify();
  • sub->Detach(a1);
  • sub->Notify();
  • }
头文件
#include "PublicHeaders.h"


#include <vector>
#include <string>

class Observer;

class Subject
{
public:
	virtual void Attach(Observer*) = 0;
	virtual void Detach(Observer*) = 0;
	virtual void Notify() = 0;

	void setState(const std::string&state)
	{
		this->_state = state;
	}
	const std::string& getState()const
	{
		return _state;
	}
private:
	std::string _state;
protected:

	std::vector<Observer*> _observers;

};


class ConCreateSubject :public Subject
{
public:
	virtual void Attach(Observer*) override;
	virtual void Detach(Observer*)override;
	virtual void Notify() override;


};

class  Observer
{
public:
	virtual void Update(const std::string &state) = 0;
};

class ConCreateObserverA :public Observer
{
public:
	virtual void Update(const std::string& state)override
	{
		if (state == "A")
		{
			cout << __FUNCTION__ << endl;
		}
	}
};


class ConCreateObserverB :public Observer
{
public:
	virtual void Update(const std::string& state)override
	{
		if (state == "B")
		{
			cout << __FUNCTION__ << endl;
		}
	}
};


void testObserver();



源文件
#include "Observer.h"

void ConCreateSubject::Attach(Observer*observer)
{
	_observers.push_back(observer);
}

void ConCreateSubject::Detach(Observer*observer)
{
	auto iter = std::find(_observers.begin(), _observers.end(), observer);
	if (iter != _observers.end())
	{
		_observers.erase(iter);
	}

}

void ConCreateSubject::Notify()
{
	for (int i = 0; i < _observers.size(); ++i)
	{
		_observers[i]->Update(this->getState());
	}
}




void testObserver()
{
	ConCreateSubject *sub = new ConCreateSubject;

	auto a1 = new ConCreateObserverA;
	sub->Attach(a1);

	auto a2 = new ConCreateObserverA;
	sub->Attach(a2);

	auto b1 = new ConCreateObserverB;
	sub->Attach(b1);

	sub->setState("A");
 
	sub->Notify();

	sub->Detach(a1);


	sub->Notify();

}

例2

游戏中实现的观察者实例

  • using UnityEngine;
  • using System.Collections;
  • using System.Collections.Generic;
  • public delegate void HandlerNotifyCenter(System.Object arg);
  • [System.Serializable]
  • class Recver
  • {
  • public string name;
  • public GameObject recver;
  • public HandlerNotifyCenter handler;
  • public Recver()
  • {
  • }
  • public void InVoke(System.Object arg)
  • {
  • handler(arg);
  • }
  • }
  • public class NotifyCenter : MonoBehaviour
  • {
  • static public NotifyCenter ins;
  • List<Recver> recvers = new List<Recver>();
  • void Awake()
  • {
  • ins = this;
  • }
  • // Use this for initialization
  • void Start()
  • {
  • }
  • // Update is called once per frame
  • void Update()
  • {
  • }
  • public void addRecver(GameObject recver, string name, HandlerNotifyCenter handler)
  • {
  • // gameObject.SendMessage(msg);
  • Recver x = new Recver();
  • x.name = name;
  • x.handler = handler;
  • x.recver = recver;
  • recvers.Add(x);
  • }
  • public void removeRecver(GameObject recver, string name)
  • {
  • foreach (Recver obj in recvers)
  • {
  • if (name == obj.name && recver == obj.recver)
  • {
  • recvers.Remove(obj);
  • }
  • }
  • }
  • public void sendMessage(string msg, System.Object arg)
  • {
  • foreach (Recver obj in recvers)
  • {
  • if (msg == obj.name)
  • {
  • obj.InVoke(arg);
  • }
  • }
  • }
  • }
  • 添加观察者
  • NotifyCenter x = NotifyCenter.ins;
  • x.addRecver(gameObject, "addCoin", new HandlerNotifyCenter(addCoin));
  • public void addCoin(System.Object obj)
  • {
  • }
using UnityEngine;
using System.Collections;
using System.Collections.Generic;


public delegate void HandlerNotifyCenter(System.Object arg);



[System.Serializable]
class Recver
{

    public string name;
    public GameObject recver;

    public HandlerNotifyCenter handler;
    public Recver()
    {


    }

    public void InVoke(System.Object arg)
    {
        handler(arg);
    }
}


public class NotifyCenter : MonoBehaviour
{
    static public NotifyCenter ins;

    List<Recver> recvers = new List<Recver>();



    void Awake()
    {
        ins = this;
    }
    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

    }



    public void addRecver(GameObject recver, string name, HandlerNotifyCenter handler)
    {
        // gameObject.SendMessage(msg);

        Recver x = new Recver();
        x.name = name;
        x.handler = handler;
        x.recver = recver;
        recvers.Add(x);
    }


    public void removeRecver(GameObject recver, string name)
    {
        foreach (Recver obj in recvers)
        {
            if (name == obj.name && recver == obj.recver)
            {
                recvers.Remove(obj);
            }
        }



    }

    public void sendMessage(string msg, System.Object arg)
    {
        foreach (Recver obj in recvers)
        {
            if (msg == obj.name)
            {
                obj.InVoke(arg);
            }
        }
    }

}



添加观察者
    NotifyCenter x = NotifyCenter.ins;
    x.addRecver(gameObject, "addCoin", new HandlerNotifyCenter(addCoin));
    public void addCoin(System.Object obj)
    {

 
    }

例3

  • class NotifyCenter
  • {
  • public:
  • static NotifyCenter *ins;
  • static NotifyCenter*getInstance()
  • {
  • if (ins == nullptr)
  • {
  • ins = new NotifyCenter;
  • }
  • return ins;
  • }
  • void SendMessage(string name, void* data)
  • {
  • auto &func = _listeners[name];
  • if (func )
  • {
  • func(data);
  • }
  • }
  • void addListener(string name, std::function<void(void*data)> callback)
  • {
  • _listeners[name] = callback;
  • }
  • private:
  • std::unordered_map< string, std::function<void(void*data)> > _listeners;
  • };
  • NotifyCenter*NotifyCenter::ins = nullptr;
  • int main()
  • {
  • //添加接受者
  • NotifyCenter::getInstance()->addListener("john", [=](void *data)
  • {//回调
  • cout << (char*)data<<" call me " << endl;
  • });
  • //添加接受者
  • NotifyCenter::getInstance()->addListener("jack", [=](void *data)
  • {
  • //回调
  • cout << (char*)data << " call me " << endl;
  • });
  • //发送消息
  • NotifyCenter::getInstance()->SendMessage("john","hk");
  • //发送消息
  • NotifyCenter::getInstance()->SendMessage("john", "");
  • //发送消息
  • NotifyCenter::getInstance()->SendMessage("11", "");
  • system("pause");
  • return 0;
  • }
class NotifyCenter
{
public:
	static NotifyCenter *ins;
	static NotifyCenter*getInstance()
	{
		if (ins == nullptr)
		{
			ins = new NotifyCenter;
		}
		return ins;
	}

	void SendMessage(string name, void* data)
	{
		auto &func = _listeners[name];
		if (func )
		{
			func(data);
		}
	}

	void addListener(string name, std::function<void(void*data)>  callback)
	{
		_listeners[name] = callback;
	}


private:
	std::unordered_map<  string, std::function<void(void*data)>  >  _listeners;

};
 
NotifyCenter*NotifyCenter::ins = nullptr;



int main()
{

	//添加接受者
	NotifyCenter::getInstance()->addListener("john", [=](void *data)
	{//回调
	
		cout << (char*)data<<"   call me " << endl;
	});

	//添加接受者

	NotifyCenter::getInstance()->addListener("jack", [=](void *data)
	{
		//回调

		cout << (char*)data << "   call me " << endl;
	});


	//发送消息
	NotifyCenter::getInstance()->SendMessage("john","hk");

	//发送消息
	NotifyCenter::getInstance()->SendMessage("john", "");

	//发送消息
	NotifyCenter::getInstance()->SendMessage("11", "");


	system("pause");

	return 0;
}

当然用vector 就能实现一对多了

Scroll Up