设计模式——Observe模式

      今天学习了下观察者模式,在软件设计过程中,常常有类似这样的情况:许多部分(对象)与某一部分(对象)之间有种状态的依赖关系,即某一对象的状态发生改变时,要通知到所有的对象。比如:有一个天气预报观察站A,许多网站向它订阅了(通过某些协议)天气提供服务,当天气预报观察站A得到了最新天气信息时,就会通知到所有与它订阅过的网站,所有订阅过天气预报服务的网站就会实时更新天气信息;某一天,有另外一家观察站,设备更先进,信息更准确,价格更便宜,于是这些网站中某一个网站退订了观察站A的服务了,当观察站A再有信息更新的时候,只会通知到当前订阅的所有网站(不包括刚退订的网站)。这就是观察者模式,此例中,这些订阅天气预报的网站就充当了观察者角色。本文就主要关注如何实现这样的订阅服务:

      首先,我们假设所有提供服务的机构都属于一个机构统一管理(这个机构提供所有的服务,如天气预报、杂志订阅……),将它抽象出来,定义一个抽象的提供者类Provider,包含订阅、退订、更新时通知所有订阅者三个方法,类关系视图如下所示:

各部分实现如下所示:

View Code
    public abstract class Provider
    {
        protected List<ICustomer> customer = new List<ICustomer>();

        //向使用者提供订阅方法(渠道)
        public void AddCustomer(ICustomer cus)
        {
            customer.Add(cus);
        }
        //向使用者提供退订方法(渠道)
        public void RemoveCustomer(ICustomer cus)
        {
            customer.Remove(cus);
        }
        //通知订阅者
        public abstract void Update();
    }

     再定义一个模拟观察站A(WeatherProvider)继承自抽象的提供者(Provider),观察站A(WeatherProvider)继承来自提供者(Provider)的订阅、退订方法,并实现了更新时通知订阅者的方法,如下:

View Code
   public class WeatherProvider:Provider
    {
        //提供天气预报的观察站名
        private string providerName;        
        //气温
        private string temperature;

        public string Temperature
        {
            get { return temperature; }
            set { temperature = value; }
        }

        public string ProviderName
        {
            get { return providerName; }
            set { providerName = value; }
        }

        public WeatherProvider(string name, string temp)
        {
            this.providerName = name;
            this.temperature = temp;
        }

        //通知所有订阅者
        public override void Update()
        {
            foreach (ICustomer cus in this.customer)
            {
                cus.SendMessage(providerName, temperature);
            }
        }
    }

      现在我们模拟一些用户群体,每个用户都必须要实现下从提供服务处获取服务数据的方法(本文比如:只提供观察站名和当前气温),为了所有订阅者统一管理,定义一个接口:

View Code
    public interface ICustomer
    {
        void SendMessage(string providerName,string temp);
    }

     此接口规定所有订阅者接受更新天气的方法。所有订阅者必须继承自此接口,规定必须实现接受更新天气的方法:

View Code
   public class Customer:ICustomer
    {
        public Customer(string name)
        {
            this.name = name;
        }

        public string name { get; set; }

        public void SendMessage(string providerName, string temp)
        {
            Console.WriteLine("Hello! " + this.name + ", We are " + providerName + " , the temperrature is " + temp + "\n");
        }
    }

    观察者模式使用演示:

View Code
   class Program
    {
        static void Main(string[] args)
        {
            //可以扩展出不同等级用户提供不同的服务内容
            ICustomer customerA = new Customer("腾讯网");
            ICustomer customerB = new Customer("新浪网");

            //可以扩展出除天气预报外不同提供服务机构
            Provider provider = new WeatherProvider("国家天气预报观察站", "10");

            //订阅
            provider.AddCustomer(customerA);
            provider.AddCustomer(customerB);

            provider.Update();

            Console.WriteLine("——————————————————————");

            //退订
            provider.RemoveCustomer(customerA);
            provider.Update();

            Console.ReadKey();
        }
    }

    程序运行结果:

     欢迎大牛们多多指点!

原文地址:https://www.cnblogs.com/yangyp/p/2807432.html