[.Net 4.0]用4.0实现基于Push的Observer模式
在4.0里,微软为我们实现基于Push的观察者模式提供了原生支持:增加了IObserver<T>和IObservable<T>两个接口。
IObserver<T>: 表示接收通知(观察器)的类。
IObservable<T>:表示发送通知(提供程序)的类;
T :表示提供通知信息的类。
下面就应这几个接口来实现常用于解释观察者模式的模型-报纸订阅。
1.创建杂志
class Magazine { private string m_Title; public string Title { get { return m_Title; } set { m_Title = value; } } private string m_Issue; public string Issue { get { return m_Issue; } set { m_Issue = value; } } public Magazine(string title, string issue) { m_Title = title; m_Issue = issue; } }
2. 接收通知的类即订阅者(这里随便取了哥名字叫Customer)class Customer : IObserver<Magazine> { private string m_Name; public string Name { get { return m_Name; } set { m_Name = value; } } public Customer(string name) { m_Name = name; } public void OnCompleted() { Console.WriteLine("订阅结束"); } public void OnError(Exception error) { throw new NotImplementedException(); } public void OnNext(Magazine magazine) { Console.WriteLine("{0}:新杂志来了!\r\n\t名称:{1}\t期号:{2}",m_Name, magazine.Title, magazine.Issue); } }
3.发送通知(提供程序)的类(报摊老板,这里假定这个老板很给力,垄断了报摊生意,全世界以后就他一个人卖报纸,不过他脾气也很怪异,随时都有可能不做生意)class TheSeller :IObservable<Magazine> { private List<IObserver<Magazine>> m_Obervers = new List<IObserver<Magazine>>(); private static readonly TheSeller m_Instance = new TheSeller(); public static TheSeller Instance { get { return TheSeller.m_Instance; } } private TheSeller() { } public Magazine GetCurrentMagazine() { var magazine = new Magazine("测试杂志?", string.Format("第{0}期", IssueSimulator.GenerateIssue())); foreach (var observer in m_Obervers) { observer.OnNext(magazine); } return magazine; } public IDisposable Subscribe(IObserver<Magazine> observer) { m_Obervers.Add(observer); return observer as IDisposable; } public bool IsCrazy() { var result = new Random().Next(1, 10) == 5; if (result) { foreach (var observer in m_Obervers) { observer.OnCompleted(); } } return result; } }
4.其他辅助类型(IssueSimulator用生成模拟期号)
static class IssueSimulator { private static int m_Issue = 1; public static int GenerateIssue() { return m_Issue++; } }
5.调用代码class Program { static void Main(string[] args) { var customer1 = new Customer("张三"); var customer2 = new Customer("李四"); TheSeller.Instance.Subscribe(customer1); TheSeller.Instance.Subscribe(customer2); while (!TheSeller.Instance.IsCrazy()) { TheSeller.Instance.GetCurrentMagazine(); Thread.Sleep(2000); } } }
