一口一个设计模式--观察者模式

     5月初,我们三个小伙伴开始着手准备机房收费系统合作版,借此大好良机,我准备把设计模式写成一个博客专栏,站在一个更高的角度品味前人的思想精髓。设计模式分为三类--创建型、结构型、行为型,咱们就先从行为型模式--观察者模式开讲。

  开讲之前,我先给大家讲个小故事,以便大家快速认识观察者模式。在战争年代,战争双方不时受到敌军飞机的轰炸,于是人们发明了航空警报,并派几个侦察兵放哨,一但敌机来临,立即拉响航空警报,这样所有的收听者就能听到报警逃跑。上述情节,看似平常,其实是观察者模式是完美体现。下图是针对上述情节的形象解说。

                              一口一个设计模式--观察者模式_第1张图片

    航空警报是个公共的接口,所有侦察兵实现了航空警报的接口,都有报警的功能。这样设计的好处是公民只需认真听航空警报是否报警即可,没必要知道是谁报的警。航空警报依赖于收听者,因为如果没有人收听,即时报警又有什么用呢?

   说到这,思想大家应该都能领悟了,但具体该如何实现呢?下面是对上图的代码实现。

航空警报代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式
{
    interface 航空警报
    {
        void 增加(收听者 listener);
        void 减少(收听者 listener);
        void 报警();
    }
}
侦察兵A代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式
{
    class 侦察兵A:航空警报
    {
        private IList<收听者> listeners = new List<收听者>();
        public void 增加(收听者 listener)
        {
            listeners.Add(listener);
        }
        public void 减少(收听者 listener)
        {
            listeners.Remove(listener);
        }
        public void 报警()
        {
            foreach (收听者 listener in listeners)
            {
                listener.逃跑();
            }
        }
    }
}
侦察兵B与侦察兵A功能相同,所以代码基本一样,在此不再赘述。

收听者代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式
{
    abstract class 收听者
    {
        protected 航空警报 airalert;
        public 收听者(航空警报 airalert)
        {
            this.airalert = airalert;
        }
        public abstract void 逃跑();
    }
}
公民A代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式
{
    class 公民A:收听者
    {
        public 公民A(航空警报 airalert):base(airalert)
        { 
        }
        public override void 逃跑()
        {
            Console.WriteLine("我是公民A,快跑,航空警报响了");
        }
    }
}
公民B与公民A身份相同,所以代码实现基本一样,在此不再赘述。

主方法代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 观察者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            侦察兵A observerA = new 侦察兵A();

            公民A citizenA = new 公民A(observerA);
            公民B citizenB = new 公民B(observerA);

            observerA.增加(citizenA);
            observerA.增加(citizenB);

            observerA.报警();

            侦察兵B observerB = new 侦察兵B();
            observerB.增加(citizenA);
            observerB.增加(citizenB);

            observerB.报警();
        }
    }
}
运行效果图:

  一口一个设计模式--观察者模式_第2张图片
     
通过运行效果图可以看出,当侦察兵A报警后,监听航空警报的公民都会收到通知逃跑,侦察兵B报警效果一样。

在C#中好比事件和委托,用委托监视事件发生,一但事件发生,委托会把事件传递给监听者,监听者对此采取相应对策。

      知识来源于生活,会生活的人才能学习好。巨人对生活进行了思考,并他们能把生活总结为一个个经典思想,而我们只是轻轻飘过,不带有一片云彩,这就是我们和巨人的差距。希望大家能留心生活的点点滴滴,它们将成为你学习知识的灵感之源。

你可能感兴趣的:(一口一个设计模式--观察者模式)