使用策略模式实现报警服务示例详解(短信报警)

 更新时间:2014年01月07日 09:19:12   作者:  
服务的功能:这个服务就是能够实现多通路报警的服务,比如邮件报警、客户端报警、短信报警等,该服务灵活性还不错,比较方便扩展

着重说一下策略模式。首先需要定义一个接口,该接口用来统一报警方法,代码如下:

复制代码 代码如下:

/// <summary>
/// 报警接口,统一各种报警方式发出报警的方法
/// </summary>
public interface IAlarm
{
  void Alarm(Message message);
}

大家伙看到Message会不会比较疑惑呢,别着急,Message就是我自己定义的一个报警的模型,比如报警标题,收件人(报警报给谁呢),报警方式(邮件、客户端等)等。

定义好接口之后,我们就要实现这个接口,实现这个接口的就是各种报警方式的类,比如EmailAlarm.cs和ClientAlarm.cs,下面是邮件报警的具体实现,EmailAlarm.cs的代码(需要实现IAlarm接口的Alarm方法):

复制代码 代码如下:

/// <summary>
/// 邮件报警
/// </summary>
public class EmailAlarm : IAlarm
{
  /// <summary>
   /// 发送邮件实现了IAlarm接口的Alarm()方法
   /// </summary>
   /// <param name="messag"></param>
   public void Alarm(Message message)
   {
    // 此处为邮件报警的具体实现代码
   }
}

下面是客户端报警的具体实现,ClientAlarm.cs(同样需要实现IAlarm接口的Alarm()方法)

复制代码 代码如下:

/// <summary>
/// 客户端报警
/// </summary>
public class ClientAlarm : IAlarm
{
     /// <summary>
     /// 实现接口IAlarm接口的Alarm()方法
     /// </summary>
     public void Alarm(Message message)
     {
         //此处为客户端实现报警的具体代码
     }
}

好了,基础工作都做完,接下来我们面临的问题是我们该如何调用不同的报警实现呢?当然,在我们的报警模型Message中有报警方式这一字段,我们需要根据报警方式这个字段来发不同的报警。这个还不简单,我们根据不同的报警方式生成不同的对象,然后各自调用Alarm()方法就ok。当然,这是一种解决方法,但是这是最好的解决方法吗?of course not!听说过反射吗,小伙伴们?接下来,我将介绍如何利用反射来调用不同的报警方式:

复制代码 代码如下:

/// <summary>
/// 统一发出各种报警的类,将所有调用报警的操作封装在这个类中,主程序需要报警时,直接调用这个类就可以,无需知道其他任何类的存在
/// </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("通过反射构造报警实例时出现异常:" + ex);
          }
       }
   }

   /// <summary>
   /// 通过发射,调用不同的报警方式
   /// </summary>
   public void HandleMessage(Message message)
   {
       foreach (AlarmWay way in Enum.GetValues(typeof(AlarmWay)))
       {
           //遍历所有的报警方式,每一种报警方式与message.AlarmWays进行按位与运算,如果运算结果仍然为当前遍历的报警方式,则说明Message中包含这种报警方式
           if ((message.AlramWays & way) == way)
           {
               try
               {
                   _alarmsDic[way].Alarm(message);
               }
               catch (Exception ex)
               {
                   //记录错误日志
               }
            }
       }
   }
}

看到AlarmWay是不是又混乱了呢?千万别乱,AlarmWay就是我定义的一个枚举类型,里面包含了各种报警方式,具体的代码我会在文章的最后贴出。我们现在还是着重讨论上面的代码,亲爱的小伙伴们,看到上面的静态构造函数了吗?知道为什么要这样写吗?我们在静态构造函数中利用反射将枚举中所有的报警对象保存在IDictionary中,具体的保存如_alarmsDic['Email'] = (IAlarm)EmailAlarm。这样做的好处小伙伴们自己琢磨吧,嘻嘻。

最后就是我们在主程序中调用AlarmContext来发出报警,具体的调用代码如下:

复制代码 代码如下:

class Program
 {
    static void Main(string[] args)
     {
        Console.WriteLine("报警服务已启动。。。");
        //message应该是从别的程序传递过来的需要报警的消息,比如在Redis队列中获取message,具体怎么获取根据需求而定。在这里为了方便,我新生成一个对象,其实不应该这样做
        Message message = new Message();
        AlarmContext context = new AlarmContext();
        context.HandleMessage(message);

     }
}

OK,到此为止,利用策略模式设计的报警服务就介绍完毕啦。这篇文章的主要知识点我认为有两个,一个是策略模式,另一个就是利用反射。希望广大的小伙伴们提出宝贵的意见,最后,贴出枚举AlarmWay的代码:

复制代码 代码如下:

/// <summary>
/// 报警方式
/// </summary>
public enum AlarmWay
{
    Email = 1,
    Client = 2,
    ShortMessage = 4
}

顺便,小伙伴们思考一下为什么ShortMessage的值是4而不是3呢?

相关文章

  • TextBox获取输入焦点时自动全选的实现方法

    TextBox获取输入焦点时自动全选的实现方法

    TextBox获取输入焦点时自动全选的实现方法,需要的朋友可以参考一下
    2013-03-03
  • C# CultureInfo之常用InvariantCulture案例详解

    C# CultureInfo之常用InvariantCulture案例详解

    这篇文章主要介绍了C# CultureInfo之常用InvariantCulture案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • 分享一个C#编写简单的聊天程序(详细介绍)

    分享一个C#编写简单的聊天程序(详细介绍)

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考。文章大体分为四个部分:程序的分析与设计、C#网络编程基础(篇外篇)、聊天程序的实现模式、程序实现
    2015-12-12
  • c#基于WinForm的Socket实现简单的聊天室 IM

    c#基于WinForm的Socket实现简单的聊天室 IM

    这篇文章主要介绍了c#基于WinForm的Socket实现简单的聊天室 IM的步骤,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-05-05
  • 使用C#判断一个字符串是否包含大写字符的五种方法

    使用C#判断一个字符串是否包含大写字符的五种方法

    本文提供了五种判断字符串是否包含大写字符的方法及其实现源码,文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-12-12
  • C#实现中文日历Calendar

    C#实现中文日历Calendar

    这篇文章介绍了C#实现中文日历Calendar的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • WPF利用TextBlock实现查找结果高亮显示效果

    WPF利用TextBlock实现查找结果高亮显示效果

    在应用开发过程中,经常遇到这样的需求:通过关键字查找数据,把带有关键字的数据显示出来,同时在结果中高亮显示关键字,所以本文就来和大家介绍一下如何利用TextBlock实现查找结果高亮显示效果吧
    2023-08-08
  • C#实现Menu和ContextMenu自定义风格及contextMenu自定义

    C#实现Menu和ContextMenu自定义风格及contextMenu自定义

    ContextMenu 类表示当用户在控件或窗体的特定区域上单击鼠标右键时会显示的快捷菜单,要想实现自定义的Menu和ContextMenu效果,大家可以通过派生ProfessionalColorTable类,下面小编把实现Menu和ContextMenu自定义风格及ContextMenu自定义给大家整理一下
    2015-08-08
  • C#创建windows系统用户的方法

    C#创建windows系统用户的方法

    这篇文章主要介绍了C#创建windows系统用户的方法,涉及C#操作用户名、密码、显示名称、描述、是否强制修改密码、密码是否过期等技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C# 计算DataTime的4种时间差的方法(相差天数、相差小时、相差分钟、相差秒)

    C# 计算DataTime的4种时间差的方法(相差天数、相差小时、相差分钟、相差秒)

    这篇文章主要介绍了C# 计算DataTime的4种时间差(相差天数、相差小时、相差分钟、相差秒),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05

最新评论