在实际项目中使用观察者模式 前篇——委托和事件

2023-05-16

我们公司面试初级C#的笔试题有一道题目:“请用代码实现:狗叫,主人被惊醒,猫跑了”。

这是一道很典型的可以使用观察者模式来解答的题目,可惜来做题的伙伴经常没有答上,今天我就从这道小题目开始,由浅到深讲讲观察者模式。

但是在讲观察者模式之前我们先要了解委托和事件。

 

委托和事件

委托(delegate)本质上是函数指针(在js里是函数变量的引用,js里并不需要声明delegate)。通俗来理解就是把一件事交给别人去做。

在代码里,“事情”就是functioin或method。delegate的作用就是把functioin或method装起来,不在new的地方执行,而在别的地方执行。

delegate需要把要执行的method注册进去,即告诉被委托人你要委托给他的事。

知道了委托,我们可以先试试水,用它来实现最开始说的笔试题的第一版。这里大家先不用去想为什么要这样做。

首先定义三位演员和他们要做的事:


    public class Dog
    {
        public void Bark()
        {
            Console.WriteLine("狗:汪汪汪");
        }
    }

    public class Master
    {
        public void WakeUp()
        {
            Console.WriteLine("主人:醒来");
        }
    }

    public class Cat
    {
        public void Run()
        {
            Console.WriteLine("猫:跑了");
        }
    }  

其次,我们把三位演员new出来,并把他们要做的事放入委托,最后通过“中介人”来执行委托:


        public delegate void TheTestDelegate();
        //定义一个中间人来执行委托,需要接收一个委托参数
        private static void Agent(TheTestDelegate doSomething) {
            doSomething();
        }

        static void Main(string[] args)
        {
            Dog dog = new Dog();
            Master master = new Master();
            Cat cat = new Cat();
            TheTestDelegate testDelegate;
            //注册要委托的事
            testDelegate = dog.Bark;
            testDelegate += master.WakeUp;
            testDelegate += cat.Run;
            //执行委托
            Agent(testDelegate);
        }  

这样一来,中间人就把我们刚刚委托给他的事都给办了

这样写的好处是显而易见的。委托将Main和各位演员的操作隔离了。每次执行委托时,我并不需要知道各位演员即将要做什么骚操作(比如狗突然喵喵叫)。从而达到了解耦的效果。

 

知道了什么是委托和委托怎么用之后,接下来我们看看什么是事件:

事件(event)是一种封装了的委托,他做了什么封装,为什么要这么封装呢?我们来继续研究上面的例子。

在上面的代码里,委托被定义成了公共的变量。这样就意味着谁都可以修改,那显然不行。

所以我们要让中介人自己管理他的委托合同。只有雇佣(new)他的人,才可以委托他干活。而作为发布人的我们仅需要发布委托和触发执行事件。

首先我们把Agent单独建一个class,但是我们要怎么让中介人自己管理委托呢?即使把delegate移到Agent里,如果将delegate声明为public,那照样谁都可以赋值。若声明为private,则谁都委托不了。

这时我们可以试试看用事件:


    //定义委托
    public delegate void TheTestDelegate();

    public class Agent
    {
        //声明事件
        public event TheTestDelegate theEvent;

        public void DoDelegate()
        {
            theEvent();
        }
    }

        static void Main(string[] args)
        {
            Agent agent = new Agent();
            //注册要委托的事
            agent.theEvent += new Dog().Bark;//注意,这里第一次不需要也不能用=号了
            agent.theEvent += new Master().WakeUp;
            agent.theEvent += new Cat().Run;
            //触发事件
            agent.DoDelegate();
        }  

大家可能觉得有疑问:这不还是用了public吗?

其实不然,为什么这里把method注册进事件不需要也不能使用“=”号了呢?

其实声明事件类似于把委托声明成了属性 (Property)。我们的+=和-=相当于访问了set访问器,而真正的delegate其实被声明成了private。

 

好了,搞了这么久,前戏终于做完了。接下来可以开始说说观察者模式了。

 

转载于:https://www.cnblogs.com/lws66/p/11218738.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在实际项目中使用观察者模式 前篇——委托和事件 的相关文章

  • 【opencv基础】OpenCV installation stuck at [ 98%] Built target opencv_perf_stitching with no error...

    前言 按照官网步骤安装opencv的过程中进行到98 时一直没有继续进行 原因 后台一直在编译运行 xff0c 只需等待即可 xff0c 参考here xff1b well turns out it gets stuck for quite
  • PX4的UORB通信机制

    在Firmware的msg文件夹里面 xff0c 里面有很多 msg结尾的文件 xff0c 这些msg文件在编译的时候可以生成h头文件 xff0c 这些编译过程中生成的头文件一般是保存在build default src module uo
  • ubuntu下安装和更新R语言

    ubuntu 下安装和更新 R 语言 本文主要讲解在 ubuntu 下如何安装和更新 R 语言 将分别介绍什么是 R 语言 xff0c 简单方法安装 R 语言 xff0c 通过更新源来安装或更新 R 语言 xff0c 和安装 R 语言集成开
  • Linux 中各个文件夹的作用

    根目录 包含了几乎所的文件目录 相当于中央系统 进入的最简单方法是 xff1a cd boot 引导程序 xff0c 内核等存放的目录 这个目录 xff0c 包括了在引导过程中所必需的文件 在最开始的启动阶段 xff0c 通过引导程序将内核
  • 转:Fix Bug的五个阶段

    一个非常严重和困难的bug xff0c 能够成就一个饱经沧桑深受压力的有经验的专业程序员的职业生涯 经受这种考验的创伤程度 xff0c 相当你受到了一次严重的身体伤害 xff0c 离婚 xff0c 或是家庭成为的离世 研究人员在研究了计算机
  • 10.app后端选择什么开发语言

    在qq上 xff0c 经常看到有创业团队的创始人一直都招不到技术人员 xff0c 除了项目的因素外 xff0c 很大的原因就是所需要掌握的开发语言偏门 通过阅读本文 xff0c 详细了解选择开发语言的核心原则 xff0c 使各位心里对开发语
  • dell服务器系统开机提示错误解决方法

    DELL 服务器有时会若硬件的改动 xff0c 在开机以后会提示错误信息 信息一般会提示在显示器上 xff0c 以后举出如下信息的解决办法 信息 原因 纠正措施 Alert iDRAC6 not responding Rebooting i
  • 卡尔曼滤波原理

    卡尔曼滤波原理 原文链接 xff1a http www bzarg com p how a kalman filter works in pictures https blog csdn net u010720661 article det
  • 在网络直播中什么叫推流

    参考 xff1a 推流 xff0c 指的是把采集阶段封包好的内容传输到服务器的过程 其实就是将现场的视频信号传到网络的过程 推流 对网络要求比较高 xff0c 如果网络不稳定 xff0c 直播效果就会很差 xff0c 观众观看直播时就会发生
  • Hello, Weka

    转自http dreamhead blogbus com logs 16813833 html Weka xff0c 是一个用Java编写的数据挖掘软件 数据挖掘 xff0c 从字面上来看 xff0c 它是一个从数据中找寻有用信息的过程 x
  • ubuntu基础知识与技巧

    root用户与超级用户的切换 1 sudo i 2 sudo su 3 su root 安装升级 查看软件xxx安装内容 dpkg L xxx 查找软件库中的软件 apt cache search 正则表达式 或 aptitude sear
  • linux多线程编程书籍推荐:linux大牛之路从这几本书開始总结

    linux多线程编程是指基于Linux操作系统下的多线程编程 xff0c 包含多任务程序的设计 xff0c 并发程序设计 网络程序设计 数据共享等 Linux系统下的多线程遵循POSIX线程接口 xff0c 称为pthread 编写Linu
  • Google Tango初学者教程

    Getting Started with the Tango Java API In this tutorial we 39 ll go through setting up your build environment and compi
  • 在虚拟机下运行gazebo,关于vmw_ioctl_command error Invalid argument错误

    开发环境 xff1a windows10 43 vmware player 43 ubuntu14 04 43 ROS indigo 运行 xff1a gazebo 前提条件 xff1a 安装gazebo xff1a sudo apt ge
  • 做杜邦线(假)教程

    好像国外叫 跳线 xff08 jump wire xff09 xff0c 我们叫杜邦线 xff0c 不清楚这个名字的来历 某宝上的杜邦线 xff0c 质量良莠不齐 xff08 如同很多别的不是杜邦线的商品一样 xff09 吃过几次亏后 xf
  • PX4的workqueue

    Workqueue相当于是中断子程序 xff0c 然后在queue的cycle里面要注意 xff0c 不能在cycle函数里面用printf打印 xff0c 在cycle里面printf函数是打印不出来的 也不能在cycle里面用while
  • windows10安装Python环境

    下载Python交互解释器 xff08 俗称 环境 xff09 登录python官网 xff1a www python org 进 入 官 网 首 页 xff0c 选 择 Downlaods 下 面 对 应 的 系 统 版 本 xff08
  • gvim背景配色

    背景 xff08 feihua 重新安装了gvim7 4后 xff08 发现gvim7 3有显示字符的bug便升级了 xff0c 忽然想改一下windows下gvim的外观 xff0c 在看了几个博客 xff0c 却发现无法设置 xff0c
  • Vue路由(vue-router)详细讲解指南

    中文文档 xff1a https router vuejs org zh Vue Router 是 Vue js 官方的路由管理器 它和 Vue js 的核心深度集成 xff0c 让构建单页面应用变得易如反掌 路由实际上就是可以理解为指向
  • Eclipse在点击运行后不能自动保存的解决

    今天在eclipse上写程序调试时 xff0c 发现当我点击运行按键之后 xff0c 并不能在运行前帮我自动保存 xff0c 也就是说每次修改代码之后 xff0c 运行的还是前一次运行之前的代码 xff0c 并不是修改之后的代码 xff0c

随机推荐

  • 自旋锁的原理实现

    import java util concurrent atomic AtomicReference boolean compareAndSet V expect V update 如果当前值 61 61 预期值 xff0c 则以原子方式将
  • 到底哪种滤波算法好?互补滤波和卡尔曼滤波结果比较(转)

    看到有人说互补滤波跟卡尔曼滤波效果差不多 xff0c 我是不相信的 不过单我自己说不行 xff0c 要有结果 xff0c 后来我就用下面的代码进行测试 xff0c 结果如下图 lt ignore js op gt 结果 xff1a 果然两滤
  • C语言RL78 serial bootloader和C#语言bootloader PC端串口通信程序

    C语言RL78 serial bootloader和C 语言bootloader PC端串口通信程序 了解更多关于bootloader 的C语言实现 xff0c 请加我QQ 1273623966 xff08 验证信息请填 bootloade
  • 几个C++ online test 网站

    http www mycppquiz com list php http www codelect net TestDetails Cplusplus Senior Level Test http careerride com c 43 4
  • CMakeLists 中file GLOB的陷阱:undefined symbol错误

    例子 xff1a 为了规范代码写了如下CMakeLists Files include file GLOB source files c h 本意是在工程中添加 h c会
  • 第五周课程总结&试验报告(三)

    第五周课程总结 amp 试验报告 xff08 三 xff09 实验三 String类的应用 实验目的 掌握类String类的使用 xff1b 学会使用JDK帮助文档 xff1b 实验内容 1 已知字符串 xff1a 34 this is a
  • vue-cli中开发生产css注入形式不同导致bug

    开发环境和生产环境不同导致的差异 主要是css层级有变动 xff1b 开发环境只是单纯的使用了style loader进行style标签插入 xff0c 不进行额外的处理 xff0c 比如说资源合并和添加md5后缀等 xff0c 这样做是为
  • 【微信原生支付】服务商模式-小微商户专属接口:小微商户新增对应APPID关联API...

    文档地址 xff1a https pay weixin qq com wiki doc api xiaowei php chapter 61 20 3 amp index 61 3 这个接口比较特殊不需要nonce str和sign typ
  • 什么是OA系统?OA系统是什么?OA是什么意思?

    什么是oa xff1f oa是 xff1a 办公自动化 xff08 Office Automation 简称OA xff09 是将现代化办公和计算机网络功能结合起来的一种新型的办公方式 办公自动化没有统一的定义 xff0c 凡是在传统的办公
  • 黑群晖DSM 6.1网卡支持列表

    黑群晖DSM 6 1网卡支持列表 Network Drivers 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • m3u8文件什么合成便于播放的MP4的方法

    先大家要知道M3U8文件不是一个视频文件 xff0c 里面全是一些路径 xff0c 说白了就是一个目录而已 xff0c 所以要看视频 xff0c 要找到对应存放视频的文件夹 如果不知道怎么找 xff0c 可以使用文本格式打开M3U8文件 x
  • ClamAV

    http www clamav net download html 转载于 https www cnblogs com diyunpeng p 5610209 html
  • C语言变量为何先定义后使用

    C语言中 xff0c 对变量的使用 xff0c 首先要先定义 说明其数据类型 原因可能如下 xff1a 1不同类型的变量 xff0c 其编码表示方式可能不同 2不同类型的变量 xff0c 其占有的空间大小不同 不事先说明无法在内存中开辟空间
  • 自定义控件sizechange问题

    自定义一个控件的时候 xff0c 放在容器里面 xff0c 显示后 xff0c 容器大小怎么改变没有异常 xff0c 但是如果把一个自定义控件放到另一个自定义控件的时候 xff0c 就有这样的问题 xff0c 就是自定义控件2成为了自定义控
  • odroid android 联想,ODROID-XU3

    En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh The ODROID XU3 is an ARM development board cr
  • 动态链接库和静态链接库的相互包含问题及实现

    动态链接库和静态链接库的基本概念请参考 1 深入理解计算机系统 第七章链接 2 程序员的自我修养 第4章 静态链接和第7章 动态链接 3 http blog jobbole com 86852 目的 为了封装代码 xff0c 简化接口 xf
  • windows下使用sed和tee命令

    最近需要在winowds slave上设置构建app和sdk xff0c 至于如何在windows slave上构建c c 43 43 代码生成sdk xff08 dll xff0c lib之类 xff09 和apk xff08 exe文件
  • 加速度计的数据解读

    一 xff1a 加速度计介绍 加速度计 是用来测试线性加速度的一种传感器 xff0c 相对于电子陀螺仪 xff0c 它具有长时间稳定的特点 但因为受到重力的影响 xff0c 短时间内会有噪声 关于加速度计的原理和结构 xff0c 可以参考我
  • Docker 命令

    For Client docker exec Run a command in a running container docker images List images docker import Import the image fro
  • 在实际项目中使用观察者模式 前篇——委托和事件

    我们公司面试初级C 的笔试题有一道题目 xff1a 请用代码实现 xff1a 狗叫 xff0c 主人被惊醒 xff0c 猫跑了 这是一道很典型的可以使用观察者模式来解答的题目 xff0c 可惜来做题的伙伴经常没有答上 xff0c 今天我就从