大话设计-观察者模式

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

如图示:

个人理解:

还是觉得大鸟和小菜的情景对话比较有意思。确实,现实当中也是会有这样的情况,公司员工不务正业,但是总是能在老板来的时候装出一副很认真的样子,说来也是奇怪,为什么他们能在第一时间知道是老板来了,然后立马投入工作呢?其实,身边也是有这样的例子:平时不想上课了,就跟关系比较好的同学说,要是老师点名的话,就给我们这些没有上课的学生们打个电话或者是在QQ群里面说一声啊,我们好赶过去。就拿后面这个例子来说吧,观察者模式在这里面被体现的淋漓尽致。一句话来描述:如果老师点名,上课的同学通知没有上课的同学去签到。

   分析:

   【完成这件事需要两步】1.上课的学生得到老师要点名的消息。2.上课的学生打电话通知逃课的学生去签到

    其实完全可以这样编写代码:声明一个老师类、一个上课的学生类、一个逃课的学生类。事件是,得到消息、发出消息、接收消息。现在是学习的面向对象编程,所以要尽量的减少类之间的耦合性,如果就这么简单的编写代码会有很大的风险,假设说:老师刚一来就跟那个要给逃课的同学发通知的那个人聊天的话,这样逃课的同学就接收不到消息啦,也就是他们就会被记旷课。所以,这不是个好办法,要尽量减少耦合性才行啊,观察者模式正好是抽象出一个观察者类和一个通知者类。目的是:降低耦合性,保证信息的畅通,主体对象在状态发生变化时,会通知所有观察者对象,使它们能过自动更新自己。

先看一下我的类图:

       

看一下这一部分的代码。

 //抽象观察者
    abstract class Observer
    {
        protected string name;
        protected Subject sub;

        public Observer(string name, Subject sub)
        {
            this.name = name;
            this.sub = sub;
        }
        public abstract void Update();
    }
<pre name="code" class="csharp"> //未逃课学生类
    class StudentA :Subject
    {
        //逃课学生列表
        private IList<Observer> observers = new List<Observer>();
        private string action;
        public void Attach(Observer observer)
        {
            observers.Add(observer);

        }
        public void Detach(Observer observer)
        {
            observers.Remove(observer);

        }

        public void Notify()
        {
            foreach (Observer o in observers)
                o.Update();
        }
        public string SubjectState
        {
            get { return action; }
            set { action = value; }
        }
    }

//逃课的学生 class StudentB : Observer { public StudentB(string name, Subject sub) : base(name, sub) { } public override void Update() { Console .WriteLine ("{0}{1}老师点名啦,速速来上课!",sub.SubjectState ,name ); } }


学到这里,我和小菜一样,都觉得这样已经达到了极致,这样就完美了。没想到,加上委托之后,事情就更加简单了,看来,代码的世界真的好神奇啊。

很简单,先声明一个委托事件:

delegate void EventHandler();

接下来就把发信息的事情交给老师好啦。(将不同类的不同方法委托给老师类的“更新”这个方法上,达到弱耦合的关系)

下面是具体的客户端代码:

 static void Main(string[] args)
        {
            Teacher hanhan = new Teacher();

             StudentB taoke1 = new StudentB("dongyahan", hanhan );
           
            hanhan.Update += new EventHandler(taoke1.Gotoschool);
            hanhan.SubjectState = "我要点名啦!";
            hanhan.Notify();
        }
关于委托这一块需要学习的东西还有很多,目前只是了解委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。使用委托的前提:委托对象所搭载的所有方法必须具有相同的原型和形式,也就是拥有相同的参数列表和返回值类型。


概括来说,观察者模式关键对象是主题subject和观察者observer,一个subject可以有数目的依赖它的observer,一旦subject的状态发生了改变,所有的observer都可以得到通知。subject发出通知时并不需要知道谁是他的观察者。而且观察者们之间也是没有任何关系。当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时应该考虑使用观察者模式。简单的说就是,一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使他们各自独立的改变和复用。




posted @ 2014-11-19 21:09  幻想泡沫  阅读(155)  评论(0编辑  收藏  举报