观察者模式

观察者模式的定义:定义对象间的一种一对多的依赖关系。当一个对象(目标对象)的状态发生变化时,所有依赖于它的对象(观察者)都得到通知并被自动更新。

我们来设想一个这样的情景,我们到报社订阅报纸,那么报社就相当于目标对象,当被订阅的报纸被印刷出来时(状态发生变化),报社就会将这些报纸发送给订阅人阅读(观察者得到通知并自动更新),其结构图如下:

public class Subject
{
    private List<Observer> observers = new List<Observer>();
    
    //添加订阅者
    public void attach(Observer observer)
    {
         observers.add(observer);
    }

    //移出订阅者
    public void detach(Observer observer)
    {
         observers.remove(observer);
    }

    //通知订阅者
    public void notifyObervers(Newspaper newspaper)
    {
        foreach(var observer in observers)
        {
             observer.update(newspaper);
        }
    }
}

public class NewspaperOffice:Subject
{
    //印刷报纸(触发通知)
    public void print()
    {
        Newspaper newspaper = new Newspaper();
        notifyObervers(newspaper);
    }
}

public class Reader:Observer
{
    //更新(阅读报纸)
    public void update(Newspaper newspaper ){}
}

public class Client
{
   public static void Main(string[] args)
   {
       Reader reader = new Reader();
       NewspaperOffice office = new NewspaperOffice();
       office.attach(reader);
       office.print();
   }
}

其实利用.Net的委托可以更好的实现观察者模式,而且用委托的话,所有观察者的方法名不需要都是update,如下代码:

public class Subject
{
    Action<Newspaper> registerMethod;
    
    //添加订阅方法
    public void attach(Action<Newspaper> method)
    {
         registerMethod+=method;
    }

    //移出订阅方法
    public void detach(Action<Newspaper> method)
    {
         registerMethod-=method;
    }

    //执行订阅方法
    public void notifyObervers(Newspaper newspaper)
    {
       registerMethod(newspaper);    
    }
}

public class NewspaperOffice:Subject
{
    //印刷报纸(触发通知)
    public void print()
    {
        Newspaper newspaper = new Newspaper();
        notifyObervers(newspaper);
    }
}

public class Reader:Observer
{
    //更新(阅读报纸)
    public void IamReadNewspaper(Newspaper newspaper ){}
}

public class Client
{
   public static void Main(string[] args)
   {
       Reader reader = new Reader();
       NewspaperOffice office = new NewspaperOffice();
       office.attach(Reader.IamReadNewspaper);
       office.print();
   }
}

但不用委托的用法也是有用的,比如,添加、移出订阅者、通知订阅者的操作是数据库的操作(把订阅者的信息存储在数据库里)

 

观察者模式的本质:触发联动。

posted @ 2015-07-11 09:23  何塞穆里尼奥  阅读(206)  评论(0编辑  收藏  举报