当前位置:  编程技术>.net/c#/asp.net

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

    来源: 互联网  发布时间:2014-10-26

    本文导语:  着重说一下策略模式。首先需要定义一个接口,该接口用来统一报警方法,代码如下: 代码如下:/// /// 报警接口,统一各种报警方式发出报警的方法/// public interface IAlarm{  void Alarm(Message message);} 大家伙看到Message会不会比较...

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

代码如下:

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

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

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

代码如下:

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

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

代码如下:

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

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

代码如下:

///
/// 统一发出各种报警的类,将所有调用报警的操作封装在这个类中,主程序需要报警时,直接调用这个类就可以,无需知道其他任何类的存在
///
public class AlarmContext
{
  private static readonly IDictionary _alarmsDic = new Dictionary();
  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);
          }
       }
   }

   ///
   /// 通过发射,调用不同的报警方式
   ///
   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的代码:

代码如下:

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

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


    
 
 

您可能感兴趣的文章:

  • Django项目使用示例步骤及代码
  • linux使用shell脚本,如何创建用户,并设置用户密码?能否给出示例?
  • 使用libpcap实现抓包程序的步骤及代码示例
  • curl不使用文件存取cookie php使用curl获取cookie示例
  • python使用循环实现批量创建文件夹示例
  • jQuery 回车事件enter使用示例
  • jquery中交替点击事件toggle方法的使用示例
  • php中的strpos使用示例
  • sql使用cast进行数据类型转换示例
  • mysql求和函数使用示例
  • c#闭包使用方法示例
  • java使用正则表达校验手机号码示例(手机号码正则)
  • 使用java执行定时任务示例
  • java的split方法使用示例
  • c++11可变参数使用示例
  • c#的params参数使用示例
  • android开发教程之switch控件使用示例
  • 使用python实现strcmp函数功能示例
  • c#使用资源文件的示例
  • 不使用php api函数实现数组的交换排序示例
  • java协变返回类型使用示例
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux下top命令详解包括top命令参数使用及结果(virt,res,shr)排序举例说明
  • 如何在Linux下使用脚本实现程序的自动重启!望各位详解!
  • linux top命令详解以及top命令的各项使用技巧详细说明
  • c# 空合并运算符“??”的使用详解
  • 在android开发中尽量不要使用中文路径的问题详解
  • 深入SQLServer中ISNULL与NULLIF的使用详解
  • MYSQL 批量替换之replace语法的使用详解
  • 汇编语言rep movsd 的使用详解
  • 使用SQL Server判断文件是否存在后再删除(详解)
  • 深入C#中使用SqlDbType.Xml类型参数的使用详解
  • 基于C语言fflush()函数的使用详解
  • 基于C++字符串替换函数的使用详解
  • Android开发笔记之:一分钟学会使用Logcat调试程序的详解
  • 深入分析Java内存区域的使用详解
  • Python Deque 模块使用详解
  • c语言中位字段与结构联合的组合使用详解
  • C#中is与As运算符号的使用详解
  • 基于DateTime.ParseExact方法的使用详解
  • 使用DateTime的ParseExact方法实现特殊日期时间的方法详解
  • 从汇编看c++的默认析构函数的使用详解
  • oracle合并列的函数wm_concat的使用详解
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3