C# 之 观察者模式示例 -- 猫捉老鼠

379 阅读2分钟

这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情


经典示例

定义对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于他的对象都会得到通知并被自动更新。

有三只动物,Tom猫,Jerry和Jack鼠,当猫叫的时候,触发事件CatShout,然后两只老鼠开始逃跑(MouseRun),我们使用观察者模式来实现

image.png

首先添加一个猫类,作为被观察者类,添加猫的属性和方法,并且在类中定义一个事件

    class Cat
    {
        //委托事件的定义
        public  delegate void Come();
        public  event  Come catCome;

        private string _name;
        private string _color;

        public Cat(string name, string color)
        {
            this._name = name;
            this._color = color;
        }

        /// <summary> 
        /// 猫来了(被观察者的状态发生改变)
        /// </summary>

        public void Conming()
        {
            Console.WriteLine(_color + _name + "-猫来了,喵喵喵~~~~");
            if (catCome == null)
            {
                catCome();//如果catCome不等于空,则调用catCome()
            }
        }
    }

添加一个老鼠类,作为观察者类,并且将观察者自身的方法注册进被观察者中定义的事件中

 class Mouse 
 { 
    private string _name; 
    private string _color; 
   
    public Mouse(string name,string color,Cat cat)
    {
 	this._name = name;
	this._color = color;
        // 把观察者自身的方法注册进被观察者的事件里面 
        cat.catCome += RunAway;
    }

    public void RunAway()
    { 
        Console.WriteLine("老猫来了"+_color + _name + "老鼠赶快跑,吱吱吱吱 ~~~"); 
    } 
} 

在主函数中实例化观察者和被观察者

class Program
    {
        static void Main(string[] args)
        {
            Cat cat = new Cat("加菲", "黄色");
            Mouse mo1 = new Mouse("杰瑞", "黄色", cat);
            /* 这样,不管新添加几个观察者,都不用修改被观察者中的代码。减少了代码出错的概率,清晰了代码结构.*/
            Mouse mo2 = new Mouse("米奇", "黑色", cat);
            Mouse mo3 = new Mouse("小二", "红色", cat);
            //所有创建出来的老鼠都会检测到

            cat.Conming();
            mo1.RunAway();
            mo2.RunAway();
            mo3.RunAway();


            Console.ReadKey();
        }
    }

image.png

事件和委托的联系和区别

  1. 事件是一种特殊的委托,或者说是受限制的委托,是委托的一种特殊应用,只能施加+=、-=操作符,两者在本质上是一个东西

  2. event Action Come;表示定义一个事件。关键字 事件类型 事件名

  3. 事件只允许用Add,Remove方法(即+=、-=)操作,这导致了他不允许在类的外部被直接触发,只能在类的内部适合的时机触发,这样增加了代码的安全性、使用时,委托常用来表达回调,事件表达外发的接口

  4. 委托和事件支持静态方法和成员方法