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之美》--张子阳,感谢!

原文地址:https://www.cnblogs.com/darrenji/p/3613011.html