iptton 发表于 2006-12-8 10:52

设计模式学习笔记 Observer

Observer(观查者)模式:
   
         类结构设计模式
         多对一的触发机制
   


    例子修改自《深入浅出设计模式(C#/JAVA版)》中例子
PS:此书貌似我借后没有剩了(大学城)

    例子可以描述为,四只老鼠对监视两只猫( micemiky 监视 tom   m1 m2 监视 mike )

   此模式重用的意义在于这段代码                Cat tom = new Cat("TOM");
                Cat mike = new Cat("mike");
                Mouse mice = new Mouse("mice",tom);
                Mouse miky = new Mouse("miky",tom);
                Mouse m1 = new Mouse("m1", mike);
                Mouse m2 = new Mouse("m2", mike);
                tom.Cry();
                mike.Run();
C#using System;
using System.Collections;
namespace VCSConsoleTest
{
   
    public interface Observer
    {
      void Response(Cat subj);
    }
    public interface Subject
    {
      void AimAt(Observer Obs);
    }
    public class Mouse:Observer
    {
      private string name;
       // private Cat subj;
      public Mouse(string name,Subject subj)
      {
            this.name=name;
            //this.subj=subj;
            subj.AimAt(this);
      }
      public void Response(Cat subj)
      {
            Console.WriteLine(name+"看见了"+subj.name+subj.doing);
      }
    }
      public class Cat:Subject
      {
            private ArrayList observers;
            public string name;
            public string doing;
            public Cat(string name)
            {
                this.name=name;
                this.doing="doing nothing...";
                this.observers=new ArrayList();
            }
            public void AimAt(Observer obs)
            {
                this.observers.Add(obs);
            }
            public void Cry(){
                this.doing=" is crying...";
                this.brocast();
                this.doing=" after cry...";
            }
            public void Run()
            {
                this.doing = " is runnig...";
                this.brocast();
                this.doing = " after runing...";
            }
            public void brocast()
            {
                foreach (Observer obs in this.observers)
                  obs.Response(this);
            }
      }
      class Client
      {
            
            static void Main(string[] args)
            {
                Cat tom = new Cat("TOM");
                Cat mike = new Cat("mike");
                Mouse mice = new Mouse("mice",tom);
                Mouse miky = new Mouse("miky",tom);
                Mouse m1 = new Mouse("m1", mike);
                Mouse m2 = new Mouse("m2", mike);
                tom.Cry();
                mike.Run();
                Console.Read();
            }
      }
}

[ 本帖最后由 iptton 于 2006-12-8 11:02 编辑 ]

iptton 发表于 2006-12-8 10:57

例子中的类设计为:

   Cat 类实例的runcry 动作会自动触发 Mouse 类实例的 response动作

程序执行结果为:

    mice 看见了 tom is crying....
      miky 看见了 tom is crying....
      m1 看见了 mike is running...
      m2 看见了 mike is running...

powerwind 发表于 2006-12-8 12:47

public Mouse(string name,Subject subj)
      {
            this.name=name;
            subj.AimAt(this);
      }

因为这个构造函数,使得我们没有Cat就不能构造Mouse

不爽

iptton 发表于 2006-12-8 12:53

模式只是在需要的场合才使用的

如果类设计中没有要求有 Mouse 和Cat 这两种互动关系,就没有使用这种模式的必要

iptton 发表于 2006-12-8 12:55

当然,定义先后的问题可以用其它方法来解决

iptton 发表于 2006-12-8 12:59

加个 Mouse::observe(Subject subj)即可

一楼的例子有很多不好的地方

书中原来的代码没有brocast()方法,
只能有一个动作( 原来的代码也只有一个cry动作,run 是我加上的 )被观察者捕获

如果要写个较善的例子,代码就过于复杂了,不利于理解Observer模式

powerwind 发表于 2006-12-8 17:27

原帖由 iptton 于 2006-12-8 12:59 发表
加个 Mouse::observe(Subject subj)即可

一楼的例子有很多不好的地方

书中原来的代码没有brocast()方法,
只能有一个动作( 原来的代码也只有一个cry动作,run 是我加上的 )被观察者捕获

如果要写个较 ...

我就是说这个啦!
呵呵



一楼的做法是只依赖构造函数来设定观察者

wool王 发表于 2006-12-9 14:28

楼主,上类图。

iptton 发表于 2006-12-9 14:32

UML还处于能勉强读明的阶段...
页: [1]
查看完整版本: 设计模式学习笔记 Observer