.NET 4.0下的观察者模式

来源:互联网 发布:节拍器软件哪个好 编辑:程序博客网 时间:2024/05/22 15:12

.NET 4.0下的观察者模式

下图是一个经典的观察者模式的结构。(图来源于wikipedia)

观察者模式被定义为解决一个对象对多个对象的依赖问题。当一个对象的状态发生改变,它会自动通知其它依赖对象。关于该设计模式的介绍可以更多参考Terrylee的.NET设计模式(19):观察者模式(Observer Pattern)。这篇文章主要介绍在 .NET 4.0 怎么实现观察者模式。

 

在.NET 4.0下位我们提供了两个观察者模式的底层接口:IObservable<T>和IObserver<T>。这两个接口定义如下:

public interface IObservable<out T>{    IDisposable Subscribe(IObserver observer);}

 

复制代码
public interface IObserver<in T>{    void OnCompleted();    void OnError(Exception error);    void OnNext(T value);}
复制代码

 

IObserable就相当于是传统模式中的Subject,而IObserver就是订阅者。现在来演示一个新闻订阅的实例:当有被订阅的新闻站点有新文章发布时,发送信息通知它的订阅者。

首先定义一个Article类,它就相当于是新闻网站中每一篇文章实体,保存着每篇文章的信息:

复制代码
class Article{   public String Title;   public DateTime Date;   public String Author;   public String Content;}
复制代码

 

然后是我们的订阅源——新闻站点:

复制代码
class News : IObservable<Article>{    //用一个list来模拟保存站点中所有的文章    private List<Article> articles = new List<Article>();    //保存的所有的订阅者信息    private List<IObserver<Article>> observers = new List<IObserver<Article>>();    public IDisposable Subscribe(IObserver<Article> observer)    {        if (!this.observers.Contains(observer))        {            this.observers.Add(observer);        }        return new unsubscribe(observers, observer);    }    private class unsubscribe : IDisposable    {        private IObserver<Article> _observer;        private List<IObserver<Article>> _observers;        public unsubscribe(List<IObserver<Article>> observers, IObserver<Article> observer)        {            this._observer = observer;            this._observers = observers;        }        public void Dispose()        {            if (this._observers != null && this._observers.Contains(this._observer))            {                this._observers.Remove(this._observer);            }        }    }    //向订阅者发送通知    private void Notify(Article article)    {        foreach (var item in this.observers)        {            item.OnNext(article);        }    }    //当有新的文章发布时通知订阅者    public void AddArticle(Article article)    {        this.articles.Add(article);        this.Notify(article);    }}
复制代码

 

下面来定义我们的订阅者。

复制代码
class Person : IObserver<Article>{    //订阅者姓名    String name;    //保存订阅的新闻站点,方便以后取消订阅    Dictionary<IObservable<Article>, IDisposable> sbscribes = new Dictionary<IObservable<Article>, IDisposable>();    public Person(String name)    {        this.name = name;    }    public void Subscribe(IObservable<Article> news)    {        IDisposable unsub = news.Subscribe(this);        sbscribes[news] = unsub;    }    public void UnSubscribe(IObservable<Article> news)    {        if (sbscribes.ContainsKey(news))        {            sbscribes[news].Dispose();            sbscribes.Remove(news);        }    }    //没有实现    public void OnCompleted()    {        throw new NotImplementedException();    }    //当订阅中出现错误的处理没有实现    public void OnError(Exception error)    {        throw new NotImplementedException();    }    //当有新的推送通知到达后的处理    public void OnNext(Article value)    {        Console.WriteLine("One News: {0}",value.Title);    }}
复制代码

 

下面我们看下运行时的代码:

复制代码
static void Main(string[] args){    News ChinaNews = new News();    News EuropeNews = new News();    Person person1 = new Person("heqichang");    Person person2 = new Person("Jim");    //我自己订阅了中国新闻和欧洲新闻    person1.Subscribe(ChinaNews);    person1.Subscribe(EuropeNews);    //Jim订阅了欧洲新闻    person2.Subscribe(EuropeNews);    EuropeNews.AddArticle(new Article()    {        Title = "New title",        Date = DateTime.Now.Date,        Author = "heqichang",        Content = "New content"    });}
复制代码

 

现在我们很多人都应该使用着智能手机,我们可能经常在手机上收到一些应用发来的推送信息,这样的模式就跟我们的观察者模式很像。  

 

扩展阅读:

Reactive Extensions,简称Rx,是以IObserable<T>以及IObserver<T>为核心的,使用LINQ方式编程的.NET扩展库。 Rx = Observables + LINQ + Schedulers。有兴趣的可以搜索一下。

以前我们订阅博客信息,依靠的都是拉文章,现在我们也可以使用“推”的方式来订阅。参看:PubSubHubbub

 

参考链接:

http://msdn.microsoft.com/zh-cn/library/dd783449(v=vs.100).aspx