观察者模式之使用委托和事件实现

我们先看一下使用抽象类实现观察者模式的类图

代码如下:

发布者(主题)类

public class Subject
    {
        private readonly List<Observer> observers = new List<Observer>();
        public void Attach(Observer observer)
        {
            observers.Add(observer);
        }

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

        public void Notify()
        {
            foreach (var item in observers)
            {
                item.DoWork();
            }
        }
    }

订阅者类

public abstract class Observer
    {
        public abstract void DoWork();
    }

//订阅类A

public class ObserverA : Observer
    {
        public override void DoWork()
        {
            Console.WriteLine("Do something for A");
        }
}

订阅类B

public class ObserverB : Observer
    {
        public override void DoWork()
        {
            Console.WriteLine("Do something for B");
        }
    }

调用类

public static void Run()
        {
            Subject subject = new Subject();
            //
            Observer a = new ObserverA();
            Observer b = new ObserverB();
            //
            subject.Attach(a);
            subject.Attach(b);
            subject.Notify();
        }

这样我们就实现了观察者模式,Subject类依赖于Observer抽象,而不直接依赖于ObserverA B具体的实现,降低了Subject与Observer之间的耦合。然而我们发现Subject类仍然要依赖于Observer抽象,能否消除这两者的耦合呢?

答案当然是可以,那就是用委托和事件来实现

具体代码如下:

public class Subject
{
    //以下为委托实现方式
        public delegate void NotifyEventHandler();

        public event NotifyEventHandler NotifyEvent;

        public void Notify ()
        {
            if (NotifyEvent != null)
            {
                DoWork();
            }
        }
    }

Observer和实现类A 、B都不用变化

实现类中事件注册方法,代码如下

public class ObserverExecutor
    {
        public static void Run()
        {
            Subject subject = new Subject();
            subject.NotifyEvent += new ObserverA().DoWork;
            subject.NotifyEvent += new ObserverB().DoWork;
            //
            subject.NotifyMsg();
        }
    }

以上就是委托和事件实现的观察者模式,我们完全消除了Subject和Observer类之间的耦合,用事件和委托实现的是不是看起来更完美一点哈

时间: 2024-11-06 18:12:05

观察者模式之使用委托和事件实现的相关文章

C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命

使用面向对象的思想 用c#控制台代码模拟猫抓老鼠 我们先来分析一下猫抓老鼠的过程 1.猫叫了 2.所有老鼠听到叫声,知道是哪只猫来了 3.老鼠们逃跑,边逃边喊:"xx猫来了,快跑啊!我是老鼠xxx" 一  双向耦合的代码 首先需要一个猫类Cat 一个老鼠类Rat 和一个测试类Program 老鼠类的代码如下 //老鼠类 public class Rat { public string Name { get; set; } //老鼠的名字 public Cat MyCat { get;

观察者模式-猫捉老鼠(委托与事件)

猫捉老鼠是一个典型的观察者模式的实现案例,在其中加入委托与事件的程序实现,将会提高代码的一个可读性,其下是代码实现: 创建一个Cat类: using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 猫捉老鼠 { /// <summary

委托、事件、Observer观察者模式的使用解析一

一.前言 委托.事件得理论我就不解释了,不会的时候觉得很难,会了发现挺简单的,回头想想其实在JavaScript中常常用到,譬如:setTimeout()就是典型的委托. 二.传统编码方式 传统的调用方式如下,如果新加语言方法需要修改SayHello方法,增加case很不方便扩展 /// <summary> /// 普通调用方式 /// </summary> public class TestOld { public void English(string name) { Cons

委托与事件

委托在底层就是一个函数的指针,委托是事件的基础. 你可以传递引用类型.值类型.但是你有没有需要传一个方法呢?传方法的过程就是委托. 消息类: public class Message { /// <summary> /// 传引用类型 /// </summary> /// <param name="msg"></param> public static void Send(string msg) { Console.WriteLine(&

浅谈委托和事件(一)

浅谈委托和事件(一) 关于委托和事件,可能是.NET或者说是面向对象编程语言中的一个比较重要又比较难以理解的概念.关于这一话题,园子里的人也写了很多文章,最经典的可能就是张子阳的C#中的委托和事件这两篇文章了,之前也看过MSDN 上的WebCast深入 "委托和事件".可能和很多人一样,刚开始读的时候,觉得很清楚,但是过了一段时间好像又忘记了委托和事件的区别,知道很久以前,在一次面试中我被问到委托和事件有什么区别,一下子就说不清了. 所以这里稍微理一下,也算是自己的一个总结.当然,还是

.NET基础拾遗(4)委托、事件、反射与特性

Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 一.委托基础 1.1 简述委托的基本原理 委托这个概念对C++程序员来说并不陌生,因为它和C++中的函数指针非常类似,很多码农也喜欢称委托为安全的函数指针.无论这一说法是否正确,委托的的确确实现了和函数指针类似的功能,那就是提供了程序回调指定方法的机制. 在委托内部,包含了一个指向某个方法的指针(这一点上委托实现机制和C++的函数指针一致),为何称其

对张子阳先生对委托和事件的两篇文章的读后思考(说得很透,内附故事一篇)

第一篇 C#中的委托和事件 第二篇 C#中的委托和事件(续) 首先,张子阳先生的这是两篇关于委托和事件间关系的文章,是目前为止我读过的介绍委托和事件以及异步调用最简明清晰文章,作者通过非常有节奏的"标题"->"问题"->"思路"->"实现"->"讲解"的结构,分步骤一步一步地将委托和事件的实现.应用与原理阐述得非常清楚,并且在行文期间将自己有趣的思考过程通过生动的语言表达了出来,使人

四、集合与泛型、委托与事件-----《大话设计模式》

一.集合与泛型   数组 集合(ArrayList) 泛型 优点 连续存储.快速从头到尾遍历和修改元素 使用大小可按需动态增加 类型安全:省去拆箱和装箱操作 缺点 创建时必须制定数组变量的大小: 两个元素之间添加元素比较困难 类型不安全,接受所有类型的数据: 导致一直进行拆箱和装箱操作,带来很大的性能消耗   public partial class Form1 : Form { IList arrayAnimal_list = new ArrayList(); //声明并初始化集合 IList

C#知识体系(二)用案例来理解委托与事件

上一篇博客讲到了LinQ和lambda的常用方法 还有很多我们未知但c#设计团队已经为我们封装好的类和方法.随着我们不断的熟悉C#语言,渐渐的就会接触到其他的知识点,委托.事件.反射.线程.同步,异步.IO.套接字...这些东西我们平常用到的不多,都是些概念性的东西,也许是因为不熟悉而可以回避了使用这些东西,不可否认的是 就算不用这些我们依然能想到问题的解决办法.但是几乎所有语言都会有这些概念,因为在某些场景它们能发挥不可思议的能力. 其实我到现在还是没有掌握委托和事件,在工作或者设计中也尽量回