当前位置: 首页 > 编程日记 > 正文

观察者模式的经典应用(猫叫 烧开水)

ExpandedBlockStart.gifCode 猫叫了 老鼠跑 主人惊醒
 1ExpandedBlockStart.gifContractedBlock.gif/**//*
 2 * 题目:
 3 * 猫叫了,所有老鼠开始逃跑,主人被惊醒,请用OO的思想描绘此过程
 4 * 1,老鼠跟主人是被动的
 5 * 2,要考虑联动性与扩展性
 6 */

 7using System;
 8using System.Collections.Generic;
 9using System.Text;
10
11ExpandedBlockStart.gifContractedBlock.gifnamespace CatCry {
12
13ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*委托,当猫叫时将信息传给所有观察者*/
14    public delegate void CatCryEventHandler(object sender, EventArgs e);
15
16ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*被观察对象*/
17ExpandedSubBlockStart.gifContractedSubBlock.gif    abstract class Subject {
18        public event CatCryEventHandler CatCryEvent;//猫叫时的事件
19ExpandedSubBlockStart.gifContractedSubBlock.gif        public void Cry(EventArgs e) {
20            this.CatCryEvent(this, e);
21        }

22ExpandedSubBlockStart.gifContractedSubBlock.gif        public void Cry() {
23            //不接收猫叫时发出的信息
24            this.CatCryEvent(thisnew EventArgs());
25        }

26    }

27
28ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*观察者*/
29ExpandedSubBlockStart.gifContractedSubBlock.gif    abstract class Observer {
30ExpandedSubBlockStart.gifContractedSubBlock.gif        public Observer() { }
31ExpandedSubBlockStart.gifContractedSubBlock.gif        public Observer(Subject subject) {
32            subject.CatCryEvent += new CatCryEventHandler(this.Notified);
33        }

34        //当猫叫时做出的反应(当收到通知时)
35        abstract protected void Notified(object sender, EventArgs e);
36    }

37
38ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*定义猫作为被观察对象*/
39ExpandedSubBlockStart.gifContractedSubBlock.gif    class Cat : Subject {
40ExpandedSubBlockStart.gifContractedSubBlock.gif        public Cat() { Console.WriteLine("猫叫了"); }
41    }

42
43ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*定义老鼠作为观察者*/
44ExpandedSubBlockStart.gifContractedSubBlock.gif    class Mouse : Observer {
45        string mouseName;
46ExpandedSubBlockStart.gifContractedSubBlock.gif        public Mouse() { }
47        public Mouse(string mouseName, Subject subject)
48ExpandedSubBlockStart.gifContractedSubBlock.gif            : base(subject) {
49            this.mouseName = mouseName;
50        }

51ExpandedSubBlockStart.gifContractedSubBlock.gif        override protected void Notified(object sender, EventArgs e) {
52            Console.WriteLine(this.mouseName + "开始逃跑");
53        }

54    }

55
56ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//*定义主人作为观察者*/
57ExpandedSubBlockStart.gifContractedSubBlock.gif    class Marster : Observer {
58ExpandedSubBlockStart.gifContractedSubBlock.gif        public Marster() { }
59ExpandedSubBlockStart.gifContractedSubBlock.gif        public Marster(Subject subject) : base(subject) { }
60ExpandedSubBlockStart.gifContractedSubBlock.gif        override protected void Notified(object sender, EventArgs e) {
61            Console.WriteLine("主人被惊醒了");
62        }

63    }

64
65ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
66    /// 功能:用观察者模式实现
67    /// 作者:allnen
68    /// 时间:2008-6-5
69    /// </summary>

70ExpandedSubBlockStart.gifContractedSubBlock.gif    class Program {
71ExpandedSubBlockStart.gifContractedSubBlock.gif        static void Main(string[] args) {
72            Cat cat = new Cat();
73            Mouse m1 = new Mouse("老鼠1", cat);
74            Mouse m2 = new Mouse("老鼠2", cat);
75
76            Marster marster = new Marster(cat);
77            cat.Cry();//猫叫了
78
79        }

80    }

81}

code   烧开水

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

namespace Delegate {
    // 热水器
    public class Heater {
       private int temperature;
       public string type = "RealFire 001";       // 添加型号作为演示
       public string area = "China Xian";         // 添加产地作为演示
       //声明委托
       public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);
       public event BoiledEventHandler Boiled; //声明事件

       // 定义BoiledEventArgs类,传递给Observer所感兴趣的信息
       public class BoiledEventArgs : EventArgs {
           public readonly int temperature;
           public BoiledEventArgs(int temperature) {
              this.temperature = temperature;
           }
       }

       // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视
       protected virtual void OnBoiled(BoiledEventArgs e) {
           if (Boiled != null) { // 如果有对象注册
              Boiled(this, e);  // 调用所有注册对象的方法
           }
       }
      
       // 烧水。
       public void BoilWater() {
           for (int i = 0; i <= 100; i++) {
              temperature = i;
              if (temperature > 95) {
                  //建立BoiledEventArgs 对象。
                  BoiledEventArgs e = new BoiledEventArgs(temperature);
                  OnBoiled(e);  // 调用 OnBolied方法
              }
           }
       }
    }

    // 警报器
    public class Alarm {
       public void MakeAlert(Object sender, Heater.BoiledEventArgs e) {
           Heater heater = (Heater)sender;     //这里是不是很熟悉呢?
           //访问 sender 中的公共字段
           Console.WriteLine("Alarm:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Alarm: 嘀嘀嘀,水已经 {0} 度了:", e.temperature);
           Console.WriteLine();
       }
    }

    // 显示器
    public class Display {
       public static void ShowMsg(Object sender, Heater.BoiledEventArgs e) {   //静态方法
           Heater heater = (Heater)sender;
           Console.WriteLine("Display:{0} - {1}: ", heater.area, heater.type);
           Console.WriteLine("Display:水快烧开了,当前温度:{0}度。", e.temperature);
           Console.WriteLine();
       }
    }

    class Program {
       static void Main() {
           Heater heater = new Heater();
           Alarm alarm = new Alarm();

           heater.Boiled += alarm.MakeAlert;   //注册方法
           heater.Boiled += (new Alarm()).MakeAlert;      //给匿名对象注册方法
           heater.Boiled += new Heater.BoiledEventHandler(alarm.MakeAlert);    //也可以这么注册
           heater.Boiled += Display.ShowMsg;       //注册静态方法

           heater.BoilWater();   //烧水,会自动调用注册过对象的方法
       }
    }
}

输出为:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Alarm:China Xian - RealFire 001:
Alarm: 嘀嘀嘀,水已经 96 度了:
Display:China Xian - RealFire 001:
Display:水快烧开了,当前温度:96度。

转载于:https://www.cnblogs.com/panbbb/archive/2008/11/10/1330695.html

相关文章:

HTML学习笔记之基本介绍

超文本标记语言 (Hyper Text Markup Language&#xff0c;HTML&#xff09;不是一种编程语言&#xff0c;而是一种标记语言&#xff0c;用一套标记标签描述网页 HTML 标记标签又被称为 HTML 标签&#xff08;HTML Tag&#xff09;&#xff0c;它是由尖括号包围的关键词&#xf…

系统分析与设计 实验一用例模型

图书管理系统系统分析及用例图 图书管理系统能够为一定数量的借阅者提供服务。每个借阅者能够拥有唯一标识其存在的编号。图书馆向每一个借阅者发放图书证&#xff0c;图书证中包含每一个借阅者的编号和个人信息。系统通过一个单独的程序为借阅者提供服务&#xff0c;不需要管理…

2017.9.12.语文

列夫尼古拉耶维奇托尔斯泰&#xff08;Лев Николаевич Толстой&#xff0c;1828年9月9日&#xff0d;1910年11月20日&#xff09;19世纪中期俄国批判现实主义作家、思想家、哲学家。 转载于:https://www.cnblogs.com/mldyz/p/7510750.html

一封会笑死人的校园情书

Kiss郝美丽&#xff1a; Sorry&#xff01;我把Miss拼成了Kiss&#xff0c;一不小心吻了你&#xff0c;实在是对不起&#xff01; 吾本良家子弟&#xff0c;正统少年&#xff0c;一向对美眉们保持一种昂首挺胸&#xff0c;目不斜视的高姿态&#xff0c;人送美名…

Java面试题之多线程同步和互斥有几种实现方法,都是什么?

线程同步是指线程之间所具有的一种制约关系&#xff0c;一个线程的执行依赖另外一个线程的消息&#xff0c;当它没有得到另一个线程的消息时应等待&#xff0c;直到消息到达时才被唤醒。 线程互斥是指对于共享的进程系统资源&#xff0c;每个线程访问时的排他性。当有若干个线程…

1)头结点,头指针,

http://blog.csdn.net/zhenyusoso/article/details/6092843 转载于:https://www.cnblogs.com/xiaoyoucai/p/7512001.html

软件测试实验--数据工厂DataFactory+MySQL数据构造

数据工厂---DataFactoryMySQL数据构造 显示成功&#xff0c;但测出来的是啥...

杀进程和取文件最近使用时间

unit uFTPclient; interface uses SysUtils,Windows,Tlhelp32; const FILE_CREATE_TIME0; //文件建立时间 FILE_MODIFY_TIME1; //修改时间 FILE_ACCESS_TIME2; //最后访问时间 type TFileTimes (ftLastAccess, ftLastWrite, ftCreation); //文件是否…

局域网常见问题

1.开启Guest用户 密码可以不设&#xff0c;这样可以只输入账号Guest&#xff0c;即可登录(互访)。但需要保证以下策略的开启。 点击“开始→运行”并输入“gpedit.msc”&#xff0c;打开组策略。依次点击“计算机配置→Windows设置→安全设置→本地策略→安全选项”&#xff0c…

visual studio 2017 中默认无法开发 Android 8.0 及以上系统的解决方案

一般默认比较旧有两个原因&#xff0c;系统版本过旧&#xff0c;Visual Studio 版本过旧。 第一步&#xff0c;将windows 更新到最新版&#xff0c;必须是windows 10 并且更新到最新。 第二步&#xff0c;将visual studio -> 工具 -> 扩展和更新 &#xff0c;安装完所有更…

软件测试--利用正交表设计测试用例

输入条件如下&#xff1a; 姓名&#xff1a;填、不填 性别&#xff1a;男、女 学历&#xff1a;小学、初中、高中、专科、本科、硕士、博士 等级&#xff1a;普通、VIP 用正交表设计测试用例 Allpairs安装及使用 输入数据时要用tab键&#xff0c;或者使用excel表格处理 测试用…

TensorFlow 实现分类操作的函数学习

函数&#xff1a;tf.nn.sigmoid_cross_entropy_with_logits(logits, targets, nameNone) 说明&#xff1a;此函数是计算logits经过sigmod函数后的交叉熵值&#xff08;即互熵损失&#xff09;&#xff0c;能帮助你更好的进行分类操作。对于一个不相互独立的离散分类任务&#x…

【推荐】极限编程的十二大原则——小版本

小版本&#xff1a;用最少的代码工作量带来最大的业务价值。 这个原则是意思是为了高度迭代&#xff0c;与客户展现开发的进展&#xff0c;小版本发布是一个可交流的好办法&#xff0c;客户可以针对性提出反馈。但小版本把模块缩得很小&#xff0c;会影响软件的整体思路连贯&am…

抓取网络文件的URL地址作附件发送

最近公司的一个项目, 把网站的前后台分离到两个不同的服务器上(后台Server在公司内部网,前台Server在互联网了).前后台用户(分别称呼:客户,公司员工)所有的上传的文件必须要存放在前台的Server上,这样客户才能无障碍访问文件.那,客户登陆前台提出咨询问题之后,公司员工回复问题…

字符串类型String总结

1.String类&#xff1a; ①Java中&#xff0c;字符串是String类的对象&#xff1b; ②Java中&#xff0c;String是引用数据类型&#xff1b; ③可以通过使用String类提供的方法来完成对字符串的操作&#xff1b; ④创建一个字符串对象之后&#xff0c;将不能更改构成字符串的字…

C# Task注意事项

1、在Task中调用主线程控件 Task.Factory.StartNew(() > {}).ContinueWith(task > {this.Invoke(new Action(() > { MessageBox.Show(this, "执行完成"); })); }); 转载于:https://www.cnblogs.com/zhyue93/p/task1.html

CSS实现网页图片预加载

#preloadedImages {width:0px;height:0px;display:inline;background-image:url(path/to/image1.png);background-image:url(path/to/image2.png);background-image:url(path/to/image3.png);background-image:url(path/to/image4.png);background-image:url();}只要在HTML里加…

软件测试--利用组合覆盖法设计测试用例

输入条件如下&#xff1a; 姓名&#xff1a;填、不填 性别&#xff1a;男、女 学历&#xff1a;小学、初中、高中、专科、本科、硕士、博士 等级&#xff1a;普通、VIP PICT安装和使用

thinkpad 61系机器(T61 X61/X61S R61)休眠掉电问题解决办法

众多61系机器用户在待机状态下一晚上耗电10%-20%。去think服务站得到的帮助是换电池&#xff0c;换主板等实验性的办法均不能解决此问题。通过多次尝试&#xff0c;我找到了行之有效的办法与大家分享。 为满足Energy Star 4.0的标准,机器在休眠模式下,机器的一些功能,比如网络唤…

Linux必知必会的目录与启动过程

第1章 /etc/目录 1.1 /etc/sysconfig/network-scripts/ifcfg-eth0 linux第一块网卡的配置文件 [rootznix ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICEeth0 HWADDR00:0c:29:cb:69:ee TYPEEthernet UUID38ad33ab-3d2b-4183-bd84-ce1766236ddd ONBOOTyes NM_CONTRO…

Oracle10g.CentOS6安装

1、文件 Oracle 10g 下载地址_Linux下载_Linux公社-Linux系统门户网站.html&#xff08;https://www.linuxidc.com/Linux/2012-02/55336.htm&#xff09; ZC&#xff1a;这里的下载链接基本都失效了...但是&#xff0c;可以看到 每个版本对应的文件名是什么&#xff0c;然后再根…

GridView中HyperLinkField的链接使用JavaScript问题

本来写好的程序&#xff0c;突然增加需求说要点链接以后刷新父页面并弹出窗口&#xff0c;弹出可以直接用Target属性&#xff0c;在网上查了查&#xff0c;DataNavigateUrlFields并不支持JavaScript&#xff0c;在别人博客上还找到了后台绑定数据的方法&#xff0c;感觉改动太大…

软件测试实验--性能测试工具LoadRunner

HP Loadrunner12的下载和安装 LoadRunner12.x简易入门教程--&#xff08;一&#xff09;回放与录制 打不开网页&#xff0c; 有脚本&#xff0c;没有关联实例&#xff0c;显示成功。 LoadRunner12安装及基本使用

sql server性能分析--执行sql次数和逻辑次数

目前在做一个项目优化时&#xff0c;想通过数据库层分析sql server系统性能&#xff0c;查了一下网上代码&#xff0c;修改了一下标题和DMVs代码&#xff0c;以下代码可以用来分析系统运行一段时间后&#xff0c;那些语句是系统忙的sql语句。做为参考。 另类使用&#xff1a; 一…

PHP-----PHP程序设计基础教程----第四章数组

4.1 初识数组 4.1.1 什么是数组 数组是一个可以存储一组或者一系列数值的变量。在PHP中&#xff0c;数组中的元素分两部分&#xff0c;分别为键&#xff08;Key&#xff09;和值&#xff08;Value&#xff09;。其中&#xff0c;“键”为元素的识别名称&#xff0c;也被称为数组…

spark编程基础--2.2scala基础知识

&#xff1a;load 读写文件 for循环表达式 对循环的控制breakable 数据结构--数组 数据结构--元祖 数据结构--列表 Range 集合 - 可变的集合可以在原集合上进行添加、更新及删除元素。 - 不可变集合一旦被创建便不能被改变&#xff0c;添加、更新及删除操作返回的是新的集合&…

BZOJ 3483 SGU505 Prefixes and suffixes(字典树+可持久化线段树)

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id3483 【题目大意】 给出一些串&#xff0c;同时给出m对前缀后缀&#xff0c;询问有多少串满足给出的前缀后缀模式&#xff0c;   题目要求强制在线 【题解】 我们对于给出的每个字符串正着插入字典树A&#xf…

石英晶体振荡器的结构

石英晶体振荡器的结构 石英晶体振荡器是利用石英晶体&#xff08;二氧化硅的结晶体&#xff09;的压电效应制成的一种谐振器件&#xff0c;它的基本构成大致是&#xff1a;从一块石英晶体上按一定方位角切下薄片&#xff08;简称为晶片&#xff0c;它可以是正方形、矩形或圆形等…

坐班族如何摆脱粗壮大腿

对于很多office lady来说一天可能会在办公室坐上八个小时甚至更多的时间&#xff0c;慢慢地会发现大腿越来越粗壮&#xff0c;其实只要认清你大腿的问题真正出在哪里&#xff1f;用一些简单的运动甚至改变坐姿&#xff0c;都可以达到阻止大腿变粗的效果……一起来看看吧&#x…

spark编程基础--2.3面向对象编程基础

类 对象 继承 参数化类型 特质 模式匹配&#xff08;match case类&#xff09; 包 类的定义 构造器 //代码文件为/usr/local/scala/mycode/Counter2.scala class Counter {private var value 0 private var name "" private var step 1 //计算器的默认递进步长 …