C#使用事件模拟:猫叫 -> 老鼠逃跑 & 主人惊醒

这是一个典型的观察者模式的应用场景,事件的发源在于猫叫这个动作,在猫叫之后,老鼠开始逃跑,而主人则会从睡梦中惊醒。可以发现,主人和老鼠这两个类型的动作相互之间没有联系,但都是由猫叫这一事件触发的。.

设计的大致思路在于,猫类包含并维护一个猫叫的动作,主人和老鼠的对象实例需要订阅猫叫这一事件,保证猫叫这一事件发生时主人和老鼠可以执行相应的动作。

(1)设计猫类,为其定义一个猫叫的事件CatCryEvent:

public class Cat
{
    private string name;
    // 猫叫的事件
    public event EventHandler<CatCryEventArgs> CatCryEvent;

    public Cat(string name)
    {
        this.name = name;
    }

    // 触发猫叫事件
    public void CatCry()
    {
        // 初始化事件参数
        CatCryEventArgs args = new CatCryEventArgs(name);
        Console.WriteLine(args);
        // 开始触发事件
        CatCryEvent(this, args);
    }
}

public class CatCryEventArgs : EventArgs
{
    private string catName;

    public CatCryEventArgs(string catName)
        : base()
    {
        this.catName = catName;
    }

    public override string ToString()
    {
        string message = string.Format("{0}叫了", catName);
        return message;
    }
}

(2)设计老鼠类,在其构造方法中订阅猫叫事件,并提供对应的处理方法

public class Mouse
{
    private string name;
    // 在构造方法中订阅事件
    public Mouse(string name, Cat cat)
    {
        this.name = name;
        cat.CatCryEvent += CatCryEventHandler;
    }

    // 猫叫的处理方法
    private void CatCryEventHandler(object sender, CatCryEventArgs e)
    {
        Run();
    }

    // 逃跑方法
    private void Run()
    {
        Console.WriteLine("{0}逃走了:我勒个去,赶紧跑啊!", name);
    }
}

(3)设计主人类,在其构造犯法中订阅猫叫事件,并提供对应的处理方法

public class Master
{
    private string name;

    // 在构造方法中订阅事件
    public Master(string name, Cat cat)
    {
        this.name = name;
        cat.CatCryEvent += CatCryEventHandler;
    }

    // 针对猫叫的处理方法
    private void CatCryEventHandler(object sender, CatCryEventArgs e)
    {
        WakeUp();
    }

    // 具体的处理方法——惊醒
    private void WakeUp()
    {
        Console.WriteLine("{0}醒了:我勒个去,叫个锤子!", name);
    }
}

(4)最后在Main方法中进行场景的模拟:

public class Program
{
    public static void Main(string[] args)
    {
        Cat cat = new Cat("假老练");
        Mouse mouse1 = new Mouse("风车车", cat);
        Mouse mouse2 = new Mouse("米奇妙", cat);
        Master master = new Master("李扯火", cat);
        // 毛开始叫了,老鼠和主人有不同的反应
        cat.CatCry();

        Console.ReadKey();
    }
}

这里定义了一只猫,两只老鼠与一个主人,当猫的CatCry方法被执行到时,会触发猫叫事件CatCryEvent,此时就会通知所有这一事件的订阅者。

本场景的关键之处就在于主人和老鼠的动作应该完全由猫叫来触发。

下面是场景模拟代码的运行结果:

C#使用事件模拟:猫叫 -> 老鼠逃跑 & 主人惊醒