`
scanfprintf123
  • 浏览: 80557 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

闲话Command模式的异常处理

阅读更多

     Command模式是GOF中较为简单的,用来封装行为的一个模式。在我们初涉设计模式的领域前,我们可能就在不知不觉中使用了它。比如说JAVA多线程中的Ruuable接口,比如说swing编程中用于处理事件的action,这些通通都是Command模式的使用。跟很多行为型模式一样,command模式用于降低接收者和发送者的耦合,我们经常可以在一些开源框架中看到,command实例对象常在层与层之间进行传递,接收者对于接收到的command,根本不知道其所能处理的业务,只知道如何调用它来执行。

 

     举我们常见的业务框架的处理来讲,每一个command对应于一个业务处理类,这些command统一在一个Front Controller中进行调用。



 

    Controller中调用command的方法:
 

#controller

      .....
      //获取command对象

     //调用command
      command.execute(ctx);

      ....

 

 

  而在我们的业务处理类即command中,我们会去调用service层的方法来获取对应的数据,并返回给页面处理。这个是一般的流程,而我们在处理过程中,我们可能会遇到多种不同的异常(一个command中需要实现的业务可能需要调用多个不同service来完成),而在command中,我们处理异常的方式大多是将异常信息记录下来,然后返回给client端一个友好的错误信息提示,或者直接抛给Front Controller进行统一的处理。如果command这一层的开发与service层的开发是由不同的人员进行的,那么对于service层抛出的异常,还需要先进行封装成command层的异常(这个也就是我们所说的异常链的转化),再抛给Front Controller进行处理。

 

#controller

try{
      .....
      //获取command对象

     //调用command
      command.execute(ctx);

      ....
}catch(xxxBizException ex)
{
      //记录异常信息
    logger.warn("xxx",ex);
      //构造一个友好的response
}

 

   当我们现实世界中的业务远不会这么简单,我们经常需要根据不同异常来构造不同的友好提示信息,如果我们把这些不同的异常都放到controller进行处理,那么每次当command需要增加新的异常处理时,都需要对controller进行修改,而且,从设计层面上讲,这些业务异常的处理是属于controller的职责吗?在我看来,controller只需要处理一些通用的异常即可,对于那些可变而且跟业务强依赖的异常,还是需要放到command自己本身来处理,但是,这样一来,command就变成了下面这个样子:

#ListingGoodCommand

public void execute(Context ctx) throws Throwable
{

    ...
    try{
      //校验权限
    Authenticator.validate(ctx.getUser);
    }catch(UserNotFoundException ex)
    {
     //记录异常
   logger.warn(ex);
     //构造用户不存在的信息
   ctx.setError("user not found");
     //直接返回,不执行后续的操作
     return;
    }catch(UserExpiredException ex)
    //记录异常
   logger.warn(ex);
     //构造用户过期的信息
   ctx.setError("user is expired.");
     //直接返回,不执行后续的操作
     return;
     }


      //获取所有的商品
    try{
          response=GoodService.listAll(ctx.getUser);
     }catch(WebServiceException ex)
     {
     //记录异常
   logger.warn(ex);
     //出现webservice异常
   ctx.setError("Can not acquier goods now.");
     //直接返回,不执行后续的操作
     return;
    }

     //其他操作
   ...
}

 

    从上可以看出,我们的command代码可读性很差,而且不易扩展。有没有什么好的方式能够统一处理异常但又不放在controller中呢?有。只需要修改下ICommand接口以及controller类即可。

   ICommand接口增加一个postProcess()方法:

  

    Controller类中增加调用ICommand#postProcess()的处理:

 

#controller

try{
      //保存发生的异常
      Throwable t=null;
      .....
      //获取command对象

     //调用command
      command.execute(ctx);

      ....
}catch(xxxBizException1 ex)
{
      //记录异常信息
    logger.warn("xxx",ex);
      //构造一个友好的response
}
catch(xxxBizException2 ex)
{
      //记录异常信息
    logger.warn("xxx",ex);
      //构造一个友好的response
}catch(Throwable ex)
{
      //保存未能进行处理的异常
    t=ex;
}

//如果有未能处理的异常,则调用ICommand#postProcess()处理
if(t!=null)
   command. postProcess(ctx,t);

 

    从上可以看出,在controller的异常处理中,我们把xxxBizException1,xxxBizException2 都当作是通用的异常进行处理,剩下的都会转发到command中去进行处理。这样,我们的ListingGoodCommand就演变成了:

 

#ListingGoodCommand

public void execute(Context ctx) throws Throwable
{

    ...
      //校验权限
    Authenticator.validate(ctx.getUser);
  
      //获取所有的商品
     response=GoodService.listAll(ctx.getUser);
         
      //其他操作
    ...
}

public void postProcess(Context ctx,Throwable t)
{
    if(t instanceof UserNotFoundException)
    {
        //记录异常
      logger.warn(ex);
        //构造用户不存在的信息
      ctx.setError("user not found");
    }

    if(t instanceof UserExpiredException)
    {
        //记录异常
        logger.warn(ex);
        //构造用户过期的信息
     ctx.setError("user is expired.");
     }

     //其他异常同理
}

 

  这样一来,我们就能够在同一个地方进行异常的处理,并且我们command中的业务逻辑变得很清晰。看到这里,眼尖的同学可能已经发现,这实际上就是Command的后Filter模式。

 

  • 大小: 5 KB
  • 大小: 1.7 KB
0
0
分享到:
评论

相关推荐

    闲话大二层

    闲话大二层分四个章节:1 闲话大二层网络(1)—数据中心为什么需要大二层网络?2 闲话大二层网络(2)—传统的二层网络为啥大不起来?3 闲话大二层网络(3)—如何实现真正意义上的大二层网络?4 闲话大二层网络(4)—跨...

    闲话矩阵求导.pdf

    在处理矩阵优化问题时,正确而高效地进行矩阵求导对于问题的解决至关重要。 矩阵求导有两种不同的布局,分别是分子布局(numerator layout)和分母布局(denominator layout)。这两种布局主要体现在导数的表示方法...

    初中语文文摘生活闲话

    2. **信息处理方式**:不同的人对待闲话的态度各异,有的选择遗忘,有的则选择保留并传播。这反映了个人对信息价值判断的差异,以及在社交中的角色定位。在IT领域,这可以类比为用户对于网络信息的选择、存储和分享...

    闲话ABSl2022年跟踪特辑超额抵押普遍正增长,助力存续

    闲话ABSl2022年跟踪特辑超额抵押普遍正增长,助力存续证券信用风险持续下降共7页.pdf.zip

    闲话矩阵求导

    ### 闲话矩阵求导 #### 一、布局(Layout) 在深入探讨矩阵求导之前,有必要先了解一下矩阵求导中的两种主要布局方式:分子布局(numerator layout)与分母布局(denominator layout)。 ##### 1. 分子布局(Numerator ...

    小学语文成语大全闲话休题成语解释

    这便是出自冯梦龙《喻世明言》的成语“闲话休题”。 首先,我们来详细解读“闲话休题”这一成语的含义和出处。正如标题和概要内容所言,“闲话休题”这一短语,来源于明朝冯梦龙的《喻世明言》。其原意是“闲话休提...

    初中语文文摘社会鼻子闲话

    初中语文文摘社会鼻子闲话

    组织沟通的大忌 闲话说不得 管理资料.doc

    在组织沟通中,存在一个至关重要但常被忽视的大忌——避免传播闲话。闲话指的是那些无关工作,缺乏建设性,甚至可能带有消极、诽谤性质的交流。这类闲话不仅无益于工作进展,反而会破坏团队合作,损害组织文化,甚至...

    读《当闲话象风一样吹来时》有感.doc

    《当闲话象风一样吹来时》这篇文章深深地触动了我,它以一个学生拾金不昧却遭误解的故事,揭示了现实生活中我们经常会遇到的一种困境:做好事却可能受到流言蜚语的困扰。这个故事提醒我们,无论在何种情况下,我们都...

    初中语文文摘生活闲话闲说

    初中语文文摘生活闲话闲说

    读《当闲话象风一样吹来时》有感作文.doc

    《当闲话象风一样吹来时》这篇文章深深地触动了我,它以一个学生的视角,探讨了社会中普遍存在的一个问题——闲话与误解。在这个故事中,主人公因为拾金不昧的行为,反而遭受了同学的误解和闲言碎语,这无疑是对善良...

    闲话WPF 不错的文档

    **闲话WPF系列概述** WPF,全称Windows Presentation Foundation,是微软.NET Framework的一部分,用于构建丰富的、具有视觉吸引力的Windows桌面应用程序。WPF引入了许多先进的技术,如XAML(Extensible ...

    翡冷翠山居闲话详案.doc

    翡冷翠山居闲话详案.doc

    论文研究-P2P网络中一种基于闲话的更新传播方法.pdf

    针对基于泛洪的更新传播方法存在开销高、可靠性和可伸缩性差等问题,提出了一种基于闲话的更新传播方法,其思想是每个副本节点将更新消息随机转发给一组邻居副本节点,副本节点向其邻居副本节点请求更新副本。...

    关于C语言程序设计课程的一些闲话课件PPT共12页.pdf

    【标题】"关于C语言程序设计课程的一些闲话课件PPT共12页.pdf" 涉及到的是C语言程序设计的学习资源,通常这样的课件会包含C语言的基础概念、语法特性以及编程技巧等内容。C语言是计算机科学中的基础编程语言,它以其...

    基于Java、CSS、JavaScript的闲话猫二手书平台设计源码

    该项目是一款基于Java、CSS和JavaScript的闲话猫二手书平台设计源码。它包含384个文件,其中包含78个PNG、78个GIF、68个JPG图片文件,以及50个Java源文件、25个CSS样式文件、23个JavaScript脚本文件、11个FTL模板...

Global site tag (gtag.js) - Google Analytics