zoukankan      html  css  js  c++  java
  • 14委托和事件在观察者模式中更好的写法

    设计智能汽车,当后面车与前方车小于50米的时候,后面车语音报警,仪表盘显示报警信息,并收到前方车的相关信息。

     

    □ 思路

    ● 前方车看作是被监视对象,后方车为观察者Observer。
    ● Observer方法需要一个与事件相关的参数,可以把这个参数封装成一个继承EventArgs。
    ● Observer方法需要一个被监视对象的参数,通过这个参数可以拿到被监视对象的public属性或字段。
    ● 被监视对象要声明委托的参数列表与Observer方法一致,并且委托符合"...EventHandler"命名惯例。
    ● 被监视对象同时需要...EventHandler类型的事件变量。
    ● 被监视对象需要一个事件触发方法,一旦事件被触发,同时会触发所有注册的Observer方法。
    ● 被监视对象同时需要一个方法,当满足某种条件就触发事件

     

    □ 代码

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Text;
       5:  using System.Threading.Tasks;
       6:   
       7:  namespace ConsoleApplication14
       8:  {
       9:      class Program
      10:      {
      11:          static void Main(string[] args)
      12:          {
      13:              SmartCar car = new SmartCar();
      14:              Alarm alarm = new Alarm();
      15:   
      16:              car.DetectDistance += alarm.MakeAlert;
      17:              car.DetectDistance += Display.ShowMsg;
      18:   
      19:              car.KeepSafety();
      20:              Console.ReadKey();
      21:          }
      22:      }
      23:   
      24:      public class SmartCar
      25:      {
      26:          private int distance;//测量与后方车的举例
      27:          public string brand = "福特";
      28:          public string type = "翼虎";
      29:   
      30:          public delegate void DetectDistanceEventHandler(Object sender, DetectDistanceEventArgs e);//声明委托
      31:          public event DetectDistanceEventHandler DetectDistance; //声明委托类型的事件
      32:   
      33:          //事件一旦被触发就调用所有的注册方法
      34:          //设计成虚方法以便让子类来继承,这样子类就可以不被观察者监视
      35:          protected virtual void OnDetectDistance(DetectDistanceEventArgs e)
      36:          {
      37:              if (DetectDistance != null)
      38:              {
      39:                  DetectDistance(this, e);
      40:              }
      41:          }
      42:   
      43:          //当侦测到与后方车的距离小于50米就触发事件
      44:          public void KeepSafety()
      45:          {
      46:              for (int i = 100; i > 48; i--)
      47:              {
      48:                  distance = i;
      49:                  if (distance < 50)
      50:                  {
      51:                      DetectDistanceEventArgs e = new DetectDistanceEventArgs(distance);
      52:                      OnDetectDistance(e);
      53:                  }
      54:              }
      55:          }
      56:      }
      57:   
      58:      //观察者事件参数
      59:      public class DetectDistanceEventArgs : EventArgs
      60:      {
      61:          public readonly int distance;
      62:   
      63:          public DetectDistanceEventArgs(int distance)
      64:          {
      65:              this.distance = distance;
      66:          }
      67:      }
      68:   
      69:      //声音警报
      70:      public class Alarm
      71:      {
      72:          public void MakeAlert(Object sender, DetectDistanceEventArgs e)
      73:          {
      74:              SmartCar car = (SmartCar)sender;
      75:              Console.WriteLine("嘀嘀嘀:与前方车距离是{0},请保持车距",e.distance);
      76:              Console.WriteLine("前方车品牌为{0},车型为{1}",car.brand, car.type);
      77:              Console.WriteLine();
      78:          }
      79:      }
      80:   
      81:      //仪表盘显示
      82:      public class Display
      83:      {
      84:          public static void ShowMsg(Object sender, DetectDistanceEventArgs e)
      85:          {
      86:              SmartCar car = (SmartCar)sender;
      87:              Console.WriteLine("请注意:与前方车距离是{0},请保持车距", e.distance);
      88:              Console.WriteLine("前方车品牌为{0},车型为{1}", car.brand, car.type);
      89:              Console.WriteLine();
      90:          }
      91:      }
      92:  }
      93:   

     

    □ 结果

    1


    □ 总结

    ● Observer方法需要一个与事件相关的参数,可以把这个参数封装成一个继承EventArgs。
    ● Observer方法需要一个被监视对象的参数,通过这个参数可以拿到被监视对象的public属性或字段。

    public void MakeAlert(Object sender, DetectDistanceEventArgs e)

     

    ● 被监视对象要声明委托的参数列表与Observer方法一致,并且委托符合"...EventHandler"命名惯例。

    public delegate void DetectDistanceEventHandler(Object sender, DetectDistanceEventArgs e);//声明委托

     

    ● 被监视对象同时需要...EventHandler类型的事件变量。

    public event DetectDistanceEventHandler DetectDistance; //声明委托类型的事件

     

    ● 被监视对象需要一个事件触发方法,一旦事件被触发,同时会触发所有注册的Observer方法。

       1:          //事件一旦被触发就调用所有的注册方法
       2:          //设计成虚方法以便让子类来继承,这样子类就可以不被观察者监视
       3:          protected virtual void OnDetectDistance(DetectDistanceEventArgs e)
       4:          {
       5:              if (DetectDistance != null)
       6:              {
       7:                  DetectDistance(this, e);
       8:              }
       9:          }

     

    ● 被监视对象同时需要一个方法,当满足某种条件就触发事件

       1:          //当侦测到与后方车的距离小于50米就触发事件
       2:          public void KeepSafety()
       3:          {
       4:              for (int i = 100; i > 48; i--)
       5:              {
       6:                  distance = i;
       7:                  if (distance < 50)
       8:                  {
       9:                      DetectDistanceEventArgs e = new DetectDistanceEventArgs(distance);
      10:                      OnDetectDistance(e);
      11:                  }
      12:              }
      13:          }   

       

    参考资料:
    《.NET之美》--张子阳,感谢!

  • 相关阅读:
    边工作边刷题:70天一遍leetcode: day 35
    边工作边刷题:70天一遍leetcode: day 36
    边工作边刷题:70天一遍leetcode: day 37-2
    边工作边刷题:70天一遍leetcode: day 37
    边工作边刷题:70天一遍leetcode: day 37-1
    边工作边刷题:70天一遍leetcode: day 38-2
    边工作边刷题:70天一遍leetcode: day 38-1
    边工作边刷题:70天一遍leetcode: day 38
    边工作边刷题:70天一遍leetcode: day 38-2
    边工作边刷题:70天一遍leetcode: day 38-1
  • 原文地址:https://www.cnblogs.com/darrenji/p/3613011.html
Copyright © 2011-2022 走看看