设计模式之观察者模式

来源:互联网 发布:ios开发需要学linux 编辑:程序博客网 时间:2024/06/03 20:46

  记得高中时我坐在靠近窗户的座位,一个早上,我们的班主任张海啸老师在外面开晨会,这时王小明、刘大方跑到我面前说:“帮个忙吧,海啸来了告诉我一声,我听会歌。”赵小军听到他们让我帮忙,也跑过来说:“刚哥,帮个忙,我聊会天,老师来了也告诉我一声。”我郁闷,谁让在座位在这呢?遇到这种情况,我立即启用观察者模式-“海啸预警中心”,进行侦测...

  观察者模式又叫发布-订阅(Publish/Subscribe)模式

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

  观察者结构图如下:

  

  由于有了这种模式,我们的“海啸预警平台”开始启用了...


   抽象类-海啸预警平台

//海啸预警平台        abstract class PlatForm        {            //需要通知的同学存在在一个集合            private IList<Player> players = new List<Player>();            //增加同学            public void Attach(Player player)            {                players.Add(player);            }            //移除不想告知的同学            public void Detach(Player player)            {                players.Remove(player);            }            //预警平台的重点是-通知            public void Notify()            {                foreach (Player p in players)   //遍历所有需要预警的同学                {                    p.Change();                }            }        }
 

具体通知者-预警小队

//预警平台组        class Team : PlatForm        {            private string teacherState;            //密切关注老师动态            public string TeacherState            {                get { return teacherState; }                set { teacherState = value; }            }        }

抽象观察者-Player

//上课玩的同学        abstract class Player        {            public abstract void Change();        }
这些人天天就知道玩,耳朵里也只能听通知来作出反应了。


具体观察者-Listener、Speaker

//听音乐的同学        class Listener : Player        {            private string name;            private string playerState;            private Team teamer;            public Listener(Team teamer, string name)            {                this.teamer = teamer;                this.name = name;            }            public override void Change()            {                playerState = teamer.TeacherState;                Console.WriteLine("{0}{1}别听音乐了", teamer.TeacherState, name);            }        }        //聊天的同学        class Speaker : Player        {            private string name;            private string playerState;            private Team teamer;            public Speaker(Team teamer, string name)            {                this.teamer = teamer;                this.name = name;            }            public override void Change()            {                playerState = teamer.TeacherState;                Console.WriteLine("{0}{1}别聊天了", teamer.TeacherState, name);            }        }

客户端代码

static void Main(string[] args)        {            Team 李贺刚 = new Team();            李贺刚.Attach(new Listener(李贺刚, "王小明"));            李贺刚.Attach(new Listener(李贺刚, "刘大方"));            李贺刚.Attach(new Speaker(李贺刚, "赵小军"));            李贺刚.TeacherState = "海啸来了,赶紧坐好";            李贺刚.Notify();            Console.Read();        }
运行结果为:



  这种观察者模式有什么特点呢?

  1.将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便;

  2.当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式;

  3.一个抽象有两个方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用;

  总之,观察者模式所做的工作其实就是解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。

  这个“海啸预警中心”还真是好,自从用了以后,老师回来后经常夸我们守纪律、都是听话的孩子。我是一个劲地汗颜啊...,当然同学们倒是非常高兴,既能玩好又被夸奖,两全其美。

  在其后的某一天,我带领着我们的预警小组去外面通宵打游戏去了,第二天的早上我们全部趴到桌子上睡觉,然后只听见一声大喊:”干什么,反了你们了。“睁开朦胧的眼一看,班主任赫然站在讲台上,一脸怒气...哎,看来”预警中心“也有失灵的时候,要是提前做个委托该多好呀...

原创粉丝点击