zoukankan      html  css  js  c++  java
  • 程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(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...

  • 相关阅读:
    mabatis的批量新增sql 初级的 初级的 初级的
    (批量更新)对多个符合条件的id做更新操作
    js中的 !! 和 ! 的区别
    js中===和==的区别
    select下拉框使用完毕后,重置按钮使其清空
    select下拉框的数据回显
    字符串拼串 能缓解我们的开发难度→!←(ε=(´ο`*)))唉,又是一个不知道该怎么写题目的随笔啊,头疼)
    select下拉框可以直接取list里的内容 不用非得转map (不得不承认我是个ZZ,这么简单的问题才反应过来,--^--)
    sql中某条件不为空,可能有的小祖宗会喷了,这还用总结?emmm,我渣,我觉得有一点意思对于第二种(土味)
    左查询left join on简单总结
  • 原文地址:https://www.cnblogs.com/wupeiqi/p/3155254.html
Copyright © 2011-2022 走看看