• 程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)


    要求:  1.要有联动性,老鼠和主人的行为是被动的。

         2.考虑可扩展性,猫的叫声可能引起其他联动效应。

    我么能事件来一步一步来实现: 将要执行的老鼠逃跑,和主人惊醒的行为注册到事件中,猫叫之后引发事件的执行!

      1、声明一个委托

    namespace ConsoleTest.MouseAndCat
    {
        public delegate void Delegate();
    }

      2、因为是由猫叫引发的事件执行,所有事件声明在猫类中

    namespace ConsoleTest.MouseAndCat
    {
        public  class Cat
        {
            public event Delegate Eventhandler;
    public void FireAway() { if (this.Eventhandler != null) { this.Eventhandler(); } } } }

      3、下面写(老鼠,主人),对其类实例化时,将要执行的行为注册到事件中

    namespace ConsoleTest.MouseAndCat
    {
        public class Master
        {
            public Master(Cat cat)
            {
                cat.Eventhandler += new Delegate(Action);
            }
            public void Action()
            {
                Console.WriteLine("主人听见了!");
            }
        }
        public class Mouse
        {
            public Mouse(Cat cat)
            {
                cat.Eventhandler += new Delegate(Action);
            }
            public void Action()
            {
                Console.WriteLine("老鼠听见了,逃跑!");
            }
        }
    }

      4、执行,执行cat的FireAwayAndWakeup方法,内部执行已注册到事件的方法

            static void Main(string[] args)
            {
                Cat cat = new Cat();
                Mouse mouse = new Mouse(cat);
                Master master = new Master(cat);
                cat.FireAway();
            }

     ---------------------------------------------------------------------------------------------

      提高一:以上已经实现了,但是考虑到可扩展性,再看第3部分的两个类中,都是在构造函数中注册事件,并且有一个执行的方法,那么如果再扩展其他的功能,比如,邻居听见...等。都需要再写相同的代码,所有我们有必要为观察者(猫叫之后,所引发的对象)提供一个父类或者接口,来统一标准,但是因为观察者都是在构造函数中进行事件的注册,而注册到事件中的方法所做的事件不同(例:老鼠逃跑、主人等),所以我们来创建一个父类(既有接口的功能,也有具体的事件),抽象类,又它来作为观察者的父类

        public abstract class Observer
        {
            public Observer(Cat cat)
            { 
                cat.Eventhandler+=new Delegate(Action);
            }
            public abstract void Action();
        }

      那么观察者的类中的也要有相应的变动

     public class Master:Observer
        {
            public Master(Cat cat):base(cat) //执行父类中的构造函数,并且将此派生类中的方法在父类的构造函数中注册到事件中
            { }
            public override void Action()    //重写抽象类中的抽象方法
            {
                Console.WriteLine("主人听见了!");
            }
        }
        public class Mouse:Observer
        {
            public Mouse(Cat cat):base(cat) //执行父类中的构造函数,并且将此派生类中的方法在父类的构造函数中注册到事件中
            {}
            public override void Action()
            {
                Console.WriteLine("老鼠听见了,逃跑!");
            }
        }

      这样一来,再对观察者进行相应的扩展的时候也就省去了些许的步骤,如果观察者多了的话,优点之处就会更加明显了。

    ----------------------------------------------------------------------------------------------------

      提高二:我们再对第2部分进行改进,这里是由 猫叫 引发的一系列的行为,但是如果我们之后又想添加 狗叫 引发这些行为的话,那么就需要再重写第2部分的那些代码,本着可扩展的目的,我们为这些引发行为的 引发者(猫、狗) 添加一个父类,父类中去实现引发事件的执行,而其派生类(阿猫、阿狗),只负责去调用其父类中的方法即可..

        public abstract class Subject
        {
            public event Delegate Eventhandler;
            public void FireAway()
            {
                if (this.Eventhandler != null)
                {
                    this.Eventhandler();
                }
            }
        }
    

      那么 引发者 只需要调用父类中的FireAway方法去执行已注册在事件中的方法即可。

     public  class Cat
        {
            public void Cry()
            {
                this.FireAway();
            }
        }
        public class Dog
        {
            public void Cry()
            {
                this.FireAway();
            }
        }

      值得注意的是,观察者 的构造函数中的参数类型,要改为引发者的父类:Subject 。因为不止可以将引发的行为(老鼠逃跑、主人醒等)添加到猫引发的事件中,还可以将其添加到狗引发的事件中。

    所以整个部分应该为:

    namespace ConsoleTest.MouseAndCat
    {
        public delegate void Delegate();
    }
    委托
        public abstract class Subject
        {
            public event Delegate Eventhandler;
            public void FireAway()
            {
                if (this.Eventhandler != null)
                {
                    this.Eventhandler();
                }
            }
        }
        public  class Cat:Subject
        {
            public void Cry()
            {
                this.FireAway();
            }
        }
      
        public class Dog:Subject
        {
            public void Cry()
            {
                this.FireAway();
            }
        }
    引发者
        public abstract class Observer
        {
            public Observer(Subject sub)
            {
                sub.Eventhandler += new Delegate(Action);
            }
            public abstract void Action();
        }
    
        public class Master:Observer
        {
            public Master(Subject sub):base(sub)
            { }
            public override void Action()
            {
                Console.WriteLine("主人听见了!");
            }
        }
        public class Mouse:Observer
        {
            public Mouse(Subject sub): base(sub)
            {}
            public override void Action()
            {
                Console.WriteLine("老鼠听见了,逃跑!");
            }
        }
    观察者
            static void Main(string[] args)
            {
                Cat cat = new Cat();
                Mouse mouse = new Mouse(cat);
                Master master = new Master(cat);
                cat.Cry();
    
                Dog dog = new Dog();
                Mouse dog_mouse = new Mouse(dog);
                Master dog_master = new Master(dog);
                dog.Cry();
    
                Console.ReadKey();
            }
    执行

    OK...

  • 相关阅读:
    5.19 省选模拟赛 T1 小B的棋盘 双指针 性质
    5.15 省选模拟赛 容斥 生成函数 dp
    5.15 省选模拟赛 T1 点分治 FFT
    5.15 牛客挑战赛40 B 小V的序列 关于随机均摊分析 二进制
    luogu P4929 【模板】舞蹈链 DLX
    CF 878E Numbers on the blackboard 并查集 离线 贪心
    5.10 省选模拟赛 拍卖 博弈 dp
    5.12 省选模拟赛 T2 贪心 dp 搜索 差分
    5.10 省选模拟赛 tree 树形dp 逆元
    luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
  • 原文地址:https://www.cnblogs.com/wupeiqi/p/3155254.html
Copyright © 2020-2023  润新知