观察者模式(维基)

https://zh.wikipedia.org/wiki/%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F

观察者模式:

subject(目标类别):

        init:初始化一个空的observer list。

        attach(register):subject有一个observer list,此操作就是为subject的observer list追加observer(listeners),一般是在创建observer的(初始化observer)时候,主动将该observer绑定到已创建的subject的observer list中。也就是在observer初始化函数中调用指定subject实例的register方法。

         detach(deregister):subject主动移除observer list对应的observer,一般由subject对象主动触发。

         notify:subject主动通知observer list所有对象,也就是遍历observer list对象,调用observer各自的update方法,一般可以写在subject完成方法后调用,例如让observer list打印或更新subject完成的更改。

observer(观察者):

       init:初始化一个将observer绑定到对应的subject,也就是调用subject的register方法,将创建的observer绑定到指定的subject的observerlist中。

       update:由绑定的subject中notify触发,也就是被动的由subject触发。

       show:由绑定的subject中notify触发,也就是被动的由subject触发。

如何理解的话就是subject主动的去操作observer除了register外的所有操作。而observer只需要初始化的时候绑定对应的subject(调用subject的register方法),然后实现自身接收notify后应该update|show的操作。

         python

class AbstractSubject(object):
    def register(self, listener):
        raise NotImplementedError("Must subclass me")
 
    def deregister(self, listener):
        raise NotImplementedError("Must subclass me")
 
    def notify_listeners(self, event):
        raise NotImplementedError("Must subclass me")
 
class Listener(object):
    def __init__(self, name, subject):
        self.name = name
        subject.register(self)
 
    def notify(self, event):
        print self.name, "received event", event
 
class Subject(AbstractSubject):
    def __init__(self):
        self.listeners = []
        self.data = None

    def getUserAction(self):
        self.data = raw_input('Enter something to do:')
        return self.data

    # Implement abstract Class AbstractSubject

    def register(self, listener):
        self.listeners.append(listener)
 
    def deregister(self, listener):
        self.listeners.remove(listener)
 
    def notify_listeners(self, event):
        for listener in self.listeners:
            listener.notify(event)

 
if __name__=="__main__":
    # make a subject object to spy on
    subject = Subject()
 
    # register two listeners to monitor it.
    listenerA = Listener("<listener A>", subject)
    listenerB = Listener("<listener B>", subject)
 
    # simulated event
    subject.notify_listeners ("<event 1>")
    # outputs:
    #     <listener A> received event <event 1>
    #     <listener B> received event <event 1>
 
    action = subject.getUserAction()
    subject.notify_listeners(action)
    #Enter something to do:hello
    # outputs:
    #     <listener A> received event hello
    #     <listener B> received event hello

        c#不需要为subject创建一个interface

using System;
using System.Collections;

namespace Wikipedia.Patterns.Strategy
{
	// IObserver --> interface for the observer
	public interface IObserver
	{
		// called by the subject to update the observer of any change
		// The method parameters can be modified to fit certain criteria
		void Update(string message);
	}

	public class Subject
	{
		// use array list implementation for collection of observers
		private ArrayList observers;

		// constructor
		public Subject()
		{
			observers = new ArrayList();
		}

		public void Register(IObserver observer)
		{
			// if list does not contain observer, add
			if (!observers.Contains(observer))
			{
				observers.Add(observer);
			}
		}

		public void Deregister(IObserver observer)
		{
			// if observer is in the list, remove
			if (observers.Contains(observer))
			{
				observers.Remove(observer);
			}
		}

		public void Notify(string message)
		{
			// call update method for every observer
			foreach (IObserver observer in observers)
			{
				observer.Update(message);
			}
		}
	}

	// Observer1 --> Implements the IObserver
	public class Observer1 : IObserver
	{
		public void Update(string message)
		{
			Console.WriteLine("Observer1:" + message);
		}
	}

	// Observer2 --> Implements the IObserver
	public class Observer2 : IObserver
	{
		public void Update(string message)
		{
			Console.WriteLine("Observer2:" + message);
		}
	}

	// Test class
	public class ObserverTester
	{
		[STAThread]
		public static void Main()
		{
			Subject mySubject = new Subject();
			IObserver myObserver1 = new Observer1();
			IObserver myObserver2 = new Observer2();

			// register observers
			mySubject.Register(myObserver1);
			mySubject.Register(myObserver2);

			mySubject.Notify("message 1");
			mySubject.Notify("message 2");
		}
	}
}

c++

#include <list>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

// The Abstract Observer
class ObserverBoardInterface
{
public:
    virtual void update(float a,float b,float c) = 0;
};

// Abstract Interface for Displays
class DisplayBoardInterface
{
public:
    virtual void show() = 0;
};

// The Abstract Subject
class WeatherDataInterface
{
public:
    virtual void registerob(ObserverBoardInterface* ob) = 0;
    virtual void removeob(ObserverBoardInterface* ob) = 0;
    virtual void notifyOb() = 0;
};

// The Concrete Subject
class ParaWeatherData: public WeatherDataInterface
{
public:
    void SensorDataChange(float a,float b,float c)
    {
        m_humidity = a;
        m_temperature = b;
        m_pressure = c;
        notifyOb();
    }

    void registerob(ObserverBoardInterface* ob)
    {
        m_obs.push_back(ob);
    }

    void removeob(ObserverBoardInterface* ob)
    {
        m_obs.remove(ob);
    }
protected:
    void notifyOb()
    {
        list<ObserverBoardInterface*>::iterator pos = m_obs.begin();
        while (pos != m_obs.end())
        {
            ((ObserverBoardInterface* )(*pos))->update(m_humidity,m_temperature,m_pressure);
            (dynamic_cast<DisplayBoardInterface*>(*pos))->show();
            ++pos;
        }
    }

private:
    float        m_humidity;
    float        m_temperature;
    float        m_pressure;
    list<ObserverBoardInterface* > m_obs;
};

// A Concrete Observer
class CurrentConditionBoard : public ObserverBoardInterface, public DisplayBoardInterface
{
public:
    CurrentConditionBoard(WeatherDataInterface& a):m_data(a)
    {
        m_data.registerob(this);
    }
    void show()
    {
        cout<<"_____CurrentConditionBoard_____"<<endl;
        cout<<"humidity: "<<m_h<<endl;
        cout<<"temperature: "<<m_t<<endl;
        cout<<"pressure: "<<m_p<<endl;
        cout<<"_______________________________"<<endl;
    }

    void update(float h, float t, float p)
    {
        m_h = h;
        m_t = t;
        m_p = p;
    }

private:
    float m_h;
    float m_t;
    float m_p;
    WeatherDataInterface& m_data;
};

// A Concrete Observer
class StatisticBoard : public ObserverBoardInterface, public DisplayBoardInterface
{
public:
    StatisticBoard(WeatherDataInterface& a):m_maxt(-1000),m_mint(1000),m_avet(0),m_count(0),m_data(a)
    {
        m_data.registerob(this);
    }

    void show()
    {
        cout<<"________StatisticBoard_________"<<endl;
        cout<<"lowest  temperature: "<<m_mint<<endl;
        cout<<"highest temperature: "<<m_maxt<<endl;
        cout<<"average temperature: "<<m_avet<<endl;
        cout<<"_______________________________"<<endl;
    }

    void update(float h, float t, float p)
    {
        ++m_count;
        if (t>m_maxt)
        {
            m_maxt = t;
        }
        if (t<m_mint)
        {
            m_mint = t;
        }
        m_avet = (m_avet * (m_count-1) + t)/m_count;
    }

private:
    float m_maxt;
    float  m_mint;
    float m_avet;
    int m_count;
    WeatherDataInterface& m_data;
};


int main(int argc, char *argv[])
{
   
    ParaWeatherData * wdata = new ParaWeatherData;
    CurrentConditionBoard* currentB = new CurrentConditionBoard(*wdata);
    StatisticBoard* statisticB = new StatisticBoard(*wdata);

    wdata->SensorDataChange(10.2, 28.2, 1001);
    wdata->SensorDataChange(12, 30.12, 1003);
    wdata->SensorDataChange(10.2, 26, 806);
    wdata->SensorDataChange(10.3, 35.9, 900);

    wdata->removeob(currentB);

    wdata->SensorDataChange(100, 40, 1900);  
    
    delete statisticB;
    delete currentB;
    delete wdata;

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值