zoukankan      html  css  js  c++  java
  • 利用自定义异常来重构代码(▄︻┻┳═一不了解自定义异常者勿看)

    ▄︻┻┳═一『异常捕获系列』Agenda:

    ▄︻┻┳═一有关于异常捕获点滴,plus我也揭揭java的短

    ▄︻┻┳═一根据异常自定义处理逻辑(【附】java异常处理规范)

    ▄︻┻┳═一利用自定义异常来重构代码


    ##先贴出来代码

    项目中有个页面,用来支付回调。窗体里无任何html元素。服务端程序Page_Load如下,即获取到请求的订单,校验订单是否有效,然后持久化订单数据,并回写处理成功或失败的标识。

     1 /// <summary>
     2 /// 由PayAndRefund/RefundForm.aspx请求过来,处理业务系统的退款请求
     3 /// </summary>
     4 public partial class RefundForm : System.Web.UI.Page
     5 {
     6     private AlipayPaymentBLL.AlipayBLL obll = new AlipayPaymentBLL.AlipayBLL();
     7     private AlipayPaymentBLL.AlipayRefundRecord alipayRefundBll = new AlipayPaymentBLL.AlipayRefundRecord();
     8     protected void Page_Load(object sender, EventArgs e)
     9     {
    10         // 记录日志和相关标记
    11         CommonUtils.LogCommon.instance.writePay(this, "===================================================================================");
    12         string sMsg = UrlInfo.Initial(Request).GetMsg();
    13         CommonUtils.LogCommon.instance.writePay(this, sMsg);
    14 
    15         ReturnValue result;
    16         try
    17         {
    18             string reqStr = WebCommon.ReadStreamReqStr(Request, System.Text.Encoding.UTF8);//获得流 序列化
    19             var refundApply = JsonConvert.DeserializeObject<CommonModel.Domains.RefundApplyDTO>(reqStr);
    20             if (refundApply == null)
    21             {
    22                 result = new ReturnValue("9999", "无通知参数");
    23             }
    24             else
    25             {
    26                 var dt = new DataTable();
    27                 var listOrderNo = new List<string>();
    28                 var dicMoney = new Dictionary<string, string>();
    29                 var dicRemark = new Dictionary<string, string>();
    30                 result = alipayRefundBll.BuilderArray(listOrderNo, dicMoney, dicRemark, refundApply);//解析传入参数信息
    31                 if (result.Code == "0000")
    32                 {
    33                     result = new AlipayPaymentBLL.AlipayRefundRecord().CheckRefundRecordOrder(listOrderNo, refundApply);
    34                     if (result.Code == "0000")
    35                     {
    36                         result = alipayRefundBll.DoRefund(refundApply, dt, listOrderNo, dicMoney, dicRemark);
    37                         if (result.Code == "0000")
    38                         {
    39                             dt.Columns.Remove("trade_no");
    40                             string[] sTableColumName = CommonModel.CommonFun.GetColumNameOfDataTable(dt);
    41                             // 将退款数据批量insert到dbo.T_AlipayRefundRecord
    42                             // 支付宝退款是有密的,这里只保存。 在单独的支付宝退款页做跳转到支付宝输入密码进行退款操作
    43                             bool bResult = alipayRefundBll.BulkCopy(dt, sTableColumName);
    44                             result = bResult ? new ReturnValue("0000", "支付宝退款请求支付中心已收到!") : new ReturnValue("9999", "退款信息入库失败!");
    45                         }
    46                     }
    47                 }
    48             }
    49         }
    50         catch (Exception ex)
    51         {
    52             CommonUtils.LogCommon.instance.writePay(this, "支付宝退款发起异常==>" + ex);
    53             result = new ReturnValue("9999", "支付宝退款发起异常");
    54         }
    55 
    56         string jsonStr = JsonConvert.SerializeObject(result);
    57         CommonUtils.LogCommon.instance.writePay(this, "支付宝退款返回值==>" + jsonStr);
    58         Response.Write(jsonStr);
    59     }
    60 }

    ##代码分析


    不考虑逻辑,仅从代码简洁的角度来看,如上代码段存在如下问题,使得代码有了坏味道(bad smell):

    * 对象oReturnValue被重复赋值并使用
    * 层层嵌套,  if和try...catch使得代码嵌套了好多层

    ##代码重构

    从如下几个角度进行重构:

    * 引入自定义异常, 当判断失败时,返回自定义异常。这样可以去掉很多if的嵌套。
    * 要对捕获到的自定义异常做处理

    重构后:

     1 /// <summary>
     2 /// 由PayAndRefund/RefundForm.aspx请求过来,处理业务系统的退款请求
     3 /// </summary>
     4 public partial class RefundForm : System.Web.UI.Page
     5 {
     6     private AlipayPaymentBLL.AlipayBLL obll = new AlipayPaymentBLL.AlipayBLL();
     7     private AlipayPaymentBLL.AlipayRefundRecord alipayRefundBll = new AlipayPaymentBLL.AlipayRefundRecord();
     8     protected void Page_Load(object sender, EventArgs e)
     9     {
    10         // 记录日志和相关标记
    11         CommonUtils.LogCommon.instance.writePay(this, "===================================================================================");
    12         string sMsg = UrlInfo.Initial(Request).GetMsg();
    13         CommonUtils.LogCommon.instance.writePay(this, sMsg);
    14 
    15         ReturnValue result;
    16         try
    17         {
    18             string reqStr = WebCommon.ReadStreamReqStr(Request, System.Text.Encoding.UTF8);//获得流 序列化
    19             var refundApply = JsonConvert.DeserializeObject<CommonModel.Domains.RefundApplyDTO>(reqStr);
    20             if (refundApply == null)
    21             {
    22                 throw new ResponseErrorException("无通知参数");
    23             }
    24 
    25             if (alipayRefundBll.RefundOrderExists(refundApply.OrderNo))
    26             {
    27                 throw new ResponseErrorException("支付宝退款请求订单号:" + refundApply.OrderNo + "已提交支付中心,请不要重复提交!");
    28             }
    29 
    30             var dt = alipayRefundBll.DoRefund1(refundApply);
    31             dt.Columns.Remove("trade_no");
    32             // 将退款数据批量insert到dbo.T_AlipayRefundRecord
    33             // 支付宝退款是有密的,这里只保存。 在单独的支付宝退款页做跳转到支付宝输入密码进行退款操作
    34             bool saveSuccess = alipayRefundBll.BulkCopy(dt);
    35             result = saveSuccess ? new ReturnValue("0000", "支付宝退款请求支付中心已收到!") : new ReturnValue("9999", "退款信息入库失败!");
    36         }
    37         catch (Exception ex)
    38         {
    39             if (ex is ResponseErrorException)
    40             {
    41                 result = new ReturnValue("9999", ex.Message);
    42             }
    43             else
    44             {
    45                 CommonUtils.LogCommon.instance.writePay(this, "支付宝退款发起异常==>" + ex.ToString());
    46                 result = new ReturnValue("9999", "支付宝退款发起异常");
    47             }
    48         }
    49 
    50         string jsonStr = JsonConvert.SerializeObject(result);
    51         CommonUtils.LogCommon.instance.writePay(this, "支付宝退款返回值==>" + jsonStr);
    52         Response.Write(jsonStr);
    53     }
    54 }

    可见,代码清晰了很多。主要的方式是引入了自定义异常ResponseErrorException,使得方法只管返回理想情况下应该返回的参数类型,而现实很骨感,所以,当不满足判断条件时,就通过抛出自定义异常的方式来实现,同时也没有破坏方法的结构。 另外,我将异常捕获统一放到了主方法ProcessRequest里,也使得代码结构清晰,少了那些if的判断,是不是很漂亮?

    public class ResponseErrorException : System.Exception
    {
        //
        // 摘要: 
        //     使用指定的错误消息初始化 ResponseErrorException 类的新实例。
        //
        // 参数: 
        //   message:
        //     描述错误的消息。
        public ResponseErrorException(string message) : base(message) { }
    
        //
        // 摘要: 使用指定的错误消息初始化 ResponseErrorException 类的新实例
        //
        // 参数: 
        //   format:
        //     复合格式字符串。
        //
        //   args:
        //     一个对象数组,其中包含零个或多个要设置格式的对象。
        //
        // 异常: 
        //   System.ArgumentNullException:
        //     format 或 args 为 null。
        //
        //   System.FormatException:
        //     format 无效。- 或 -格式项的索引小于零或大于等于 args 数组的长度。
        public ResponseErrorException(string format, params object[] args)
            : base(FormatString(format, args)) { }
    
        static string FormatString(string format, params object[] args)
        {
            try
            {
                string message = string.Format(format, args);
                return message;
            }
            catch (FormatException ex)
            {
                //LogHelper.Write("执行string.Format时(内容:"{0}",参数个数:{1})出现格式异常:{2}", format, args.Length, ex.Message);
                return string.Empty;
            }
        }
    }
  • 相关阅读:
    VUE-周日历的实现
    Mac电脑部分网页打不开怎么办
    python pytesseracct WinError2
    Windows Error的错误代码
    python pytesseract——3步识别验证码的识别入门
    python——pyinstaller踩的坑 UnicodeDecodeError
    python 处理excel踩过的坑——data_only,公式全部丢失
    Python3行代码之——截图工具
    python openpyxl内存不主动释放 ——关闭Excel工作簿后内存依旧(MemoryError)
    pywintypes.com_error: (-2147352567, '发生意外 解决方案
  • 原文地址:https://www.cnblogs.com/buguge/p/6186862.html
Copyright © 2011-2022 走看看