zoukankan      html  css  js  c++  java
  • 观察者模式(发布、订阅)之(上) 李朝强 李朝强

    什么是观察者模式?

    摘自百度百科的说法:观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

     说白了,就是一个主题,可以有N多个观察者,一个观察者,也可以订阅N多个主题。当一个主题,发生改变时,会通知订阅它的观察者,观察者收到通知后,可以做相应的处理。观察者模式,是软件设计模式中的一种。接下里,我们介绍下,使用C#实现的观察者模式。附上代码。

          首先,我们新建一个名为AppObserver的控制台项目。结构如下:

     Strategy目录下新建两个接口,一个IObserver(观察者)、一个ISubject(主题)。让我们看看,这两个接口分别定义了什么?

    /*
     * Created by http://www.lichaoqiang.com
     * User: 李朝强
     * Date: 2016/9/2
     * Time: 16:25
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    using System.Collections.Generic;
    
    namespace AppObserver.Strategy
    {
    	/// <summary>
    	/// Description of ISubject.
    	/// </summary>
    	public interface ISubject
    	{
    		/// <summary>
    		/// 主题
    		/// </summary>
    		string Title{get;set;}
    		
    		/// <summary>
    		/// 观察者
    		/// </summary>
    		List<IObserver> Observers{get;}
    		
    		/// <summary>
    		/// 添加订阅
    		/// </summary>
    		/// <param name="observer"></param>
    		void AddObserver(IObserver observer);
    		
    		/// <summary>
    		/// 发布
    		/// </summary>
    		void Publish();
    	}
    }
    

    观察者接口(IObserver):

    /*
     * Created by http://www.lichaoqiang.com
     * User: 李朝强
     * Date: 2016/9/2
     * Time: 16:27
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    using System.Collections.Generic;
    
    namespace AppObserver.Strategy
    {
    	/// <summary>
    	/// Description of IObserver.
    	/// </summary>
    	public interface IObserver
    	{
    		
    		/// <summary>
    		/// 名称
    		/// </summary>
    		string Name{get;}
    		
    		/// <summary>
    		/// 主题
    		/// </summary>
    		List<ISubject> Subjects{get;}
    		
    		/// <summary>
    		/// 通知
    		/// </summary>
    		void Notify(ISubject subject);
    		
    		/// <summary>
    		/// 订阅
    		/// </summary>
    		/// <param name="subject"></param>
    		void Subscribe(ISubject subject);
    		
    		
    		/// <summary>
    		/// 取消订阅
    		/// </summary>
    		/// <param name="subject"></param>
    		void Unsubscribe(ISubject subject);
    		
    	}
    }
    

    接下来,新建一个Support文件夹,提供对以上两个接口的实现。具体代码如下:

    主题:

    /*
     * Created by http://www.lichaoqiang.com
     * User: 李朝强
     * Date: 2016/9/2
     * Time: 16:34
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    using System.Collections.Generic;
    using AppObserver.Strategy;
    
    namespace AppObserver.Support
    {
    	/// <summary>
    	/// Description of Subject.
    	/// </summary>
    	public class Subject:ISubject
    	{
    		
    		/// <summary>
    		/// 构造函数
    		/// </summary>
    		public Subject()
    		{
    			Observers = new List<IObserver>();
    		}
    		
    		#region ISubject implementation
    		
    		/// <summary>
    		/// 添加观察者
    		/// </summary>
    		/// <param name="observer"></param>
    		void ISubject.AddObserver(IObserver observer)
    		{
    			Observers.Add(observer);
    		}
     
    		/// <summary>
    		/// 发布
    		/// </summary>
    		void ISubject.Publish()
    		{
    			if (null != Observers && Observers.Count > 0)
    				foreach (var item in Observers) {item.Notify(this);}
    		}
    	
    		/// <summary>
    		/// 主题
    		/// </summary>
    		string ISubject.Title {
    			get;
    			set;
    		}
    	
    		/// <summary>
    		/// 观察者
    		/// </summary>
    		public	List<IObserver> Observers { get; private set; }
    		#endregion
    		
    	}
    }
    

    观察者:

    /*
     * Created by http://www.lichaoqiang.com
     * User: 李朝强
     * Date: 2016/9/2
     * Time: 16:37
     * 
     * To change this template use Tools | Options | Coding | Edit Standard Headers.
     */
    using System;
    using System.Collections.Generic;
    using AppObserver.Strategy;
    
    namespace AppObserver.Support
    {
    	/// <summary>
    	/// 观察者
    	/// </summary>
    	public class Observer:IObserver
    	{
    		
    		/// <summary>
    		/// 构造函数
    		/// </summary>
    		public Observer()
    		{
    			Subjects = new List<ISubject>();
    		}
    		
    		/// <summary>
    		/// 构造函数
    		/// </summary>
    		/// <param name="name"></param>
    		public Observer(String name)
    			: this()
    		{
    			Name = name;
    		}
    
    		#region IObserver implementation
    		
    		/// <summary>
    		/// 名字
    		/// </summary>
    		public string Name{ get; private set; }
    		
    		
    		/// <summary>
    		/// 通知
    		/// </summary>
    		void IObserver.Notify(ISubject subject)
    		{
    			//这里具体可以处理你的业务逻辑
    			//我们可以通过扩展suject对象,来传递信息
    			Console.WriteLine("【{0}】收到最新通知(Notify)主题:{1}", this.Name, subject.Title);
    		}
    
    		/// <summary>
    		/// 订阅
    		/// </summary>
    		/// <param name="subject">主题</param>
    		void IObserver.Subscribe(ISubject subject)
    		{
    			subject.AddObserver(this);
    			Subjects.Add(subject);
    		}
    		
    		/// <summary>
    		/// 取消订阅
    		/// </summary>
    		/// <param name="subject">主题</param>
    		void IObserver.Unsubscribe(ISubject subject)
    		{
    		   
    		}
     
    		
    		/// <summary>
    		///获取已订阅的主题
    		/// </summary>
    		public	List<ISubject> Subjects { get; private set; }
    
    		#endregion
    	}
    }
    

    完成以上几步,就简单的实现了观察者模式。让我们一起来看看效果吧。

    场景:张三和李四两个人,一个爱好体育和娱乐,一个爱好体育。于是,张三,拿起IiPhone 6s plus,打开App,点击并订阅了《体育频道》、《娱乐频道》两个栏目,李四看了,也马上掏出小米5s,以迅雷不及掩耳盗铃之势,打开相同的APP,也同样订阅了《体育频道》这档栏目。就在这个时候,远在千里之外的一座大都市,一个S身材的MZ,坐在办公桌前,准备好了资讯内容,准备这个时候,向广大粉丝,推送这些信息。于是,她先把准备好的体育信息,标题为“张继科XXXX”的主题,推送出去。然后,接着隔壁同事老王,负责《娱乐频道》的有痣青年,把主题为《王宝强XXXX》的信息,推送出去。这个时候,张三和李四的手机,不约而同的响起了一声清脆的声音。打开一看,效果如下:

    张三和李四,顿时沉迷其中,认认真真的阅读起了这些内容。

     张三、李四虚构故事,以娱大家,博君一笑,夫复何求哈。

  • 相关阅读:
    [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.5.1
    [再寄小读者之数学篇](2014-11-21 关于积和式的一个不等式)
    简单的Slony-I设置实例
    Slony-I的限制
    PPAS上运行pg_dump经过II
    PPAS上运行pg_dump经过
    PL/pgSQL学习笔记之十一
    PL/pgSQL学习笔记之十
    PL/pgSQL学习笔记之九
    PL/pgSQL学习笔记之八
  • 原文地址:https://www.cnblogs.com/ibeisha/p/observer.html
Copyright © 2011-2022 走看看