工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 2012|回复: 8

设计模式学习笔记 Observer

[复制链接]
发表于 2006-12-8 10:52 | 显示全部楼层 |阅读模式
Observer(观查者)模式:
     
         类结构设计模式
         多对一的触发机制
     



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

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

   此模式重用的意义在于这段代码
  1.                 Cat tom = new Cat("TOM");
  2.                 Cat mike = new Cat("mike");
  3.                 Mouse mice = new Mouse("mice",tom);
  4.                 Mouse miky = new Mouse("miky",tom);
  5.                 Mouse m1 = new Mouse("m1", mike);
  6.                 Mouse m2 = new Mouse("m2", mike);
  7.                 tom.Cry();
  8.                 mike.Run();
复制代码

C#
  1. using System;
  2. using System.Collections;
  3. namespace VCSConsoleTest
  4. {
  5.    
  6.     public interface Observer
  7.     {
  8.         void Response(Cat subj);
  9.     }
  10.     public interface Subject
  11.     {
  12.         void AimAt(Observer Obs);
  13.     }
  14.     public class Mouse:Observer
  15.     {
  16.         private string name;
  17.        // private Cat subj;
  18.         public Mouse(string name,Subject subj)
  19.         {
  20.             this.name=name;
  21.             //this.subj=subj;
  22.             subj.AimAt(this);
  23.         }
  24.         public void Response(Cat subj)
  25.         {
  26.             Console.WriteLine(name+"看见了"+subj.name+subj.doing);
  27.         }
  28.     }
  29.         public class Cat:Subject
  30.         {
  31.             private ArrayList observers;
  32.             public string name;
  33.             public string doing;
  34.             public Cat(string name)
  35.             {
  36.                 this.name=name;
  37.                 this.doing="doing nothing...";
  38.                 this.observers=new ArrayList();
  39.             }
  40.             public void AimAt(Observer obs)
  41.             {
  42.                 this.observers.Add(obs);
  43.             }
  44.             public void Cry(){
  45.                 this.doing=" is crying...";
  46.                 this.brocast();
  47.                 this.doing=" after cry...";
  48.             }
  49.             public void Run()
  50.             {
  51.                 this.doing = " is runnig...";
  52.                 this.brocast();
  53.                 this.doing = " after runing...";
  54.             }
  55.             public void brocast()
  56.             {
  57.                 foreach (Observer obs in this.observers)
  58.                     obs.Response(this);
  59.             }
  60.         }
  61.         class Client
  62.         {
  63.             [STAThread]
  64.             static void Main(string[] args)
  65.             {
  66.                 Cat tom = new Cat("TOM");
  67.                 Cat mike = new Cat("mike");
  68.                 Mouse mice = new Mouse("mice",tom);
  69.                 Mouse miky = new Mouse("miky",tom);
  70.                 Mouse m1 = new Mouse("m1", mike);
  71.                 Mouse m2 = new Mouse("m2", mike);
  72.                 tom.Cry();
  73.                 mike.Run();
  74.                 Console.Read();
  75.             }
  76.         }
  77. }
复制代码

[ 本帖最后由 iptton 于 2006-12-8 11:02 编辑 ]
 楼主| 发表于 2006-12-8 10:57 | 显示全部楼层
例子中的类设计为:

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

程序执行结果为:
    mice 看见了 tom is crying....
        miky 看见了 tom is crying....
        m1 看见了 mike is running...
        m2 看见了 mike is running...
回复

使用道具 举报

发表于 2006-12-8 12:47 | 显示全部楼层
public Mouse(string name,Subject subj)
        {
            this.name=name;
            subj.AimAt(this);
        }

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

不爽
回复

使用道具 举报

 楼主| 发表于 2006-12-8 12:53 | 显示全部楼层
模式只是在需要的场合才使用的

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

使用道具 举报

 楼主| 发表于 2006-12-8 12:55 | 显示全部楼层
当然,定义先后的问题可以用其它方法来解决
回复

使用道具 举报

 楼主| 发表于 2006-12-8 12:59 | 显示全部楼层
加个 Mouse::observe(Subject subj)即可

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

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

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

使用道具 举报

发表于 2006-12-8 17:27 | 显示全部楼层
原帖由 iptton 于 2006-12-8 12:59 发表
加个 Mouse::observe(Subject subj)即可

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

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

如果要写个较 ...


我就是说这个啦!
呵呵



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

使用道具 举报

发表于 2006-12-9 14:28 | 显示全部楼层
楼主,上类图。
回复

使用道具 举报

 楼主| 发表于 2006-12-9 14:32 | 显示全部楼层
UML还处于能勉强读明的阶段...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-8-31 07:57

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表