陷阱2:“调用委托像调用方法一样简单”

  上一篇博文分析了设计模式中“观察者模式”常被忽略的两个细节:“异常”和“阻塞”。本文将使用委托重写上文“观察者模式”中的小故事。同时和大家一起看看,调用委托是不是像调用方法一样简单。

  [观察者模式中"主题类"代码示例]

/// <summary>
    /// 通过委托发送通知的主题
    /// </summary>
    public class DelegateSubject
    {
        //委托定义
        public delegate void NotifyEventHandler(string msg);
        //委托实例(观察者接收消息的委托实例)
        public NotifyEventHandler NotifyObservers = null;

        //主题名称:如天气
        public string SubjectName { get; set; }
        //发布的消息
        public string Message { get; set; }

        //主题构造函数 
        public DelegateSubject(string subjectName)
        {
            SubjectName = subjectName;
        }

        //通过委托发送通知(调用观察者接收消息的方法)
        public void Notify()
        {
            NotifyEventHandler tempNotifyHander = NotifyObservers;
            if (tempNotifyHander != null)
            {
          //调用委托像调用方法一样简单。?
                tempNotifyHander(Message);
            }
        }
    }

  [观察者模式中"观察者类"代码示例]

/// <summary>
    /// 具体观察者
    /// </summary>
    public class ConcreteObserver : IObserver
    {
        //观察者名称:如学校、公司
        public string ObserverName { get; set; }
        //观察者能识别的天气
        string[] weather = { "毛毛雨", "大雨","晴天" };
     
        //构造观察者对象
        public ConcreteObserver(string observerName)
        {
            ObserverName = observerName;
        }

        //收到天气主题发来的通知
        public void NewMessage(string msg)
        {
            if (weather.Contains(msg))  //观察者能识别的天气
            {
                Console.WriteLine(ObserverName + "收到新通知:" + msg);
                Thread.Sleep(2000);
                Console.WriteLine(ObserverName + "收到新通知,处理了2s");
            }
            else                        //突然来了鬼天气...
            {
                Console.WriteLine(ObserverName + "收到新通知:" + msg);
                Console.WriteLine(ObserverName + "被吓坏了,没见过这鬼天气!!!乱套了...");
                throw new Exception(ObserverName + "没处理好" + msg + ",出异常了");
            }
        }
    }

  [测试代码示例]

private static void TestDelegateObserverPattern()
        {
            try
            {
                DelegateSubject subject_Weather = new DelegateSubject("天气");

                IObserver observer_School = new ConcreteObserver("学校");
                IObserver observer_Company = new ConcreteObserver("公司");

                subject_Weather.NotifyObservers += observer_School.NewMessage;
                subject_Weather.NotifyObservers += observer_Company.NewMessage;

                subject_Weather.Message = "毛毛雨";
                subject_Weather.Notify();

                Console.WriteLine();

                subject_Weather.Message = "飓风";
                subject_Weather.Notify();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }