The policy pattern is used to implement the alarm service example to explain of SMS alarm in detail

  • 2020-06-01 10:56:07
  • OfStack

Focus on 1 strategic pattern. First, we need to define an interface, which is used to unify the alarm method. The code is as follows:


/// <summary>
///  Alarm interface, system 1 The method of sending out alarms by various alarm modes 
/// </summary>
public interface IAlarm
{
  void Alarm(Message message);
}

Don't worry. Message is one of the alarm models defined by me, such as the alarm title, the recipient (to whom the alarm should be reported), and the alarm mode (mail, client, etc.).

After the interface is defined, we need to implement this interface, which is implemented by various alarm classes, such as EmailAlarm.cs and ClientAlarm.cs. The following is the specific implementation of email alarm, and the code of EmailAlarm.cs (Alarm method of IAlarm interface needs to be implemented) :


/// <summary>
///  Email alert 
/// </summary>
public class EmailAlarm : IAlarm
{
  /// <summary>
   ///  Sending mail is done IAlarm Of the interface Alarm() methods 
   /// </summary>
   /// <param name="messag"></param>
   public void Alarm(Message message)
   {
    //  Here is the specific implementation code of mail alarm 
   }
}

The following is the specific implementation of the client side alarm, ClientAlarm.cs (also need to implement Alarm() method of IAlarm interface).


/// <summary>
///  Client alarm 
/// </summary>
public class ClientAlarm : IAlarm
{
     /// <summary>
     ///  Implementing an interface IAlarm Of the interface Alarm() methods 
     /// </summary>
     public void Alarm(Message message)
     {
         // Here is the client side to achieve the specific code of alarm 
     }
}

Ok, now that we've done the groundwork, the question is how do we call the different alarm implementations? Of course, there is the field of alarm mode in our alarm model Message, and we need to send different alarms according to the field of alarm mode. This is not easy, we generate different objects according to different alarm methods, and then call the Alarm() method to ok. Sure, that's one solution, but is that the best solution? of course not! Ever heard of reflection, folks? Next, I'll show you how to use reflection to invoke different alarm methods:


/// <summary>
///  system 1 Send out a variety of alarm classes, will call all alarm operations encapsulated in this class, when the main program needs to alarm, directly call this class can, do not need to know the existence of any other classes 
/// </summary>
public class AlarmContext
{
  private static readonly IDictionary<AlarmWay,IAlarm> _alarmsDic = new Dictionary<AlarmWay, IAlarm>();
  static AlarmContext()
   {
    foreach (AlarmWay way in Enum.GetValues(typeof (AlarmWay)))
       {
      try
          {
        Assembly asm = Assembly.GetExecutingAssembly();
        Object obj = asm.CreateInstance("MOPlatform.Alert." + way + "Alarm", true);
              IAlarm alarm = obj as IAlarm;
              _alarmsDic[way] = alarm;
          }
          catch (Exception ex)
          {
              Logger.Error(" When the alarm instance is detected through the reflection structure, an exception occurs: " + ex);
          }
       }
   }
   /// <summary>
   ///  By firing, different alarm modes are invoked 
   /// </summary>
   public void HandleMessage(Message message)
   {
       foreach (AlarmWay way in Enum.GetValues(typeof(AlarmWay)))
       {
           // Go through all the alarm modes, each 1 A kind of alarm and message.AlarmWays Carry out bitwise and operation, if the operation result is still the current traversal of the alarm, it is stated Message Contains this type of alarm 
           if ((message.AlramWays & way) == way)
           {
               try
               {
                   _alarmsDic[way].Alarm(message);
               }
               catch (Exception ex)
               {
                   // Error logging 
               }
            }
       }
   }
}

Is AlarmWay confusing again? Please don't be confused. AlarmWay is an enumeration type defined by me, which contains various alarm methods. I will post the specific code at the end of this article. Let's focus on the code above, dear friends, see the static constructor above? You know why I wrote that? We use reflection in the static constructor to save all alarm objects in the enumeration in IDictionary, such as _alarmsDic['Email'] = (IAlarm)EmailAlarm. The advantage of doing so is that you can figure it out for yourself, hee hee.

Finally, we call AlarmContext in the main program to send an alarm. The specific calling code is as follows:


class Program
 {
    static void Main(string[] args)
     {
        Console.WriteLine(" Alarm service activated... ");
        //message Should be from another program to pass the alarm message, such as in Redis Queue fetch message, How you get it depends on your needs. I'm going to do it here just for convenience 1 I'm not supposed to do that 
        Message message = new Message();
        AlarmContext context = new AlarmContext();
        context.HandleMessage(message);
     }
}

OK, so much for the introduction of the alarm service designed using the policy mode. I think there are two main points in this article, one is the strategy pattern, and the other is the use of reflection. I hope you can give me your valuable comments. Finally, please post the enum code of AlarmWay:


/// <summary>
///  Alarm way 
/// </summary>
public enum AlarmWay
{
    Email = 1,
    Client = 2,
    ShortMessage = 4
}

By the way, why is ShortMessage 4 instead of 3?


Related articles: