Spiga

模式开发之旅(17):观察者模式

2010-08-16 15:30:51

观察者模式:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

观察者模式的应用场景非常广泛,小到代码层面的解耦,大到架构层面的系统解耦,再或者一些产品的设计思路,都有这种模式的影子,比如,邮件订阅、RSS Feeds,本质上都是观察者模式。不同的应用场景和需求下,这个模式也有截然不同的实现方式,有同步阻塞的实现方式,也有异步非阻塞的实现方式;有进程内的实现方式,也有跨进程的实现方式。

一般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项目开发中,这两种对象的称呼是比较灵活的,有各种不同的叫法,比如:Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener。不管怎么称呼,只要应用场景符合刚刚给出的定义,都可以看作观察者模式。

观察者模式是一个比较抽象的模式,根据不同的应用场景和需求,有完全不同的实现方式。现在,我们来看其中最经典的一种实现方式。

public interface Subject
{
    void RegisterObserver(Observer observer);
    void RemoveObserver(Observer observer);
    void NotifyObservers(Message message);
}
public interface Observer 
{
    void Update(Message message); 
}

public class ConcreteSubject : Subject 
{
    private IList<Observer> observers = new List<Observer>();
    public void RegisterObserver(Observer observer)
    {
        observers.Add(observer);
    } 
    public void RemoveObserver(Observer observer) 
    {
        observers.Remove(observer); 
    }
    public void NotifyObservers(Message message) 
    {
        foreach (var observer in observers)
        {
            observer.Update(message);
        }
    }
}
public class ConcreteObserverOne : Observer
{
    public void Update(Message message) 
    {
        //TODO: 获取消息通知,执行自己的逻辑... 
        Console.WriteLine("ConcreteObserverOne is notified.");
    }
}
public class ConcreteObserverTwo : Observer
{
    public void Update(Message message) 
    {
        //TODO: 获取消息通知,执行自己的逻辑... 
        Console.WriteLine("ConcreteObserverTwo is notified.");
    }
}
public class Demo 
{
    public static void main(string[] args) 
    {
        ConcreteSubject subject = new ConcreteSubject();
        subject.RegisterObserver(new ConcreteObserverOne());
        subject.RegisterObserver(new ConcreteObserverTwo()); 
        subject.NotifyObservers(new Message());
    }
}