持续重构,其乐无穷。

一:发现问题

  先来说如何重构业务层的try{}catch{}finally{}代码块,我看过很多代码,异常处理这一块大致分为两种情况,一种是每个方法都大量的充斥着try{}catch{}finally{},这种方式的编程已经考虑到了异常处理,还有一种就是没有try{}catch{}finally{}的代码,因为根本就没有考虑代码的异常处理。每当我看到这样的代码,我都很忧伤。从程序的健壮性来看第一种还是要比第二种情况好,至少在编程意识中,随时想到了异常情况,有一种基本的编程思想。

  比如:一个业务单据的多表插入,关联修改,虚拟删除等都是一些基本的操作,但是又是比较容易引起错误的操作,在这些方法上都会加上try{}catch{}finally{}对代码进行有效的防错处理。早期的代码是这样的。

public Boolean Save(AccountModel accountData)
{Boolean result = false;try{//TODO ...result = true;}catch{}finally{ }return result;
}public Boolean Edit(AccountModel accountData)
{Boolean result = false;try{//TODO ...result = true;}catch{}finally{}return result;
}public Boolean VirDelete(AccountModel accountData)
{Boolean result = false;try{//TODO ...result = true;}catch{}finally{}return result;
}

仅仅定义了添加,修改,删除几个空方法,就写了三四十行代码,如果业务稍微复杂些,异常处理的代码很快就会突破百行大关。虽然复制,粘贴try{}catch{}finally{}很好使,但是业务逻辑代码大量充斥着这样的try{}catch{}finally{}代码,确实显得做事不够利落。

二:解决问题

  那怎样来解决这件棘手的事呢,首先定义一个公用的try{}catch{}finally{},如下如示:

public class Process
{public static bool Execute(Action action){try{action.Invoke();return true;}catch (Exception ex){//1,异常隐藏//2,异常替换//3,异常封装//写日志return false;}finally{}}
}

上边的代码定义了公用的try{}catch{}finally{},最关键是怎么运用起来,如下代码:

protected void Page_Load(object sender, EventArgs e)
{AccountModel accountData = new AccountModel();     //准备传入的参数Boolean result = false;                            //接收返回的值Process.Execute(() => result = Save(accountData)); //执行方法
}public Boolean Save(AccountModel accountData)
{Boolean result = false;//TODO ...result = true;return result;
}public Boolean Edit(AccountModel accountData)
{Boolean result = false;//TODO ...result = true;return result;
}public Boolean VirDelete(AccountModel accountData)
{Boolean result = false;//TODO ...result = true;return result;
}

这样的精简过的代码,是不是感觉心情很舒畅。

三:提升与扩展

  对于知足者常乐的人来说,到第二个步骤就可以洗洗睡了。但是对于精益求精的人来说,问题仍然没有完。我们来说一个应用场景,在WCF中的应用,我们知道WCF服务端的异常,不经过<serviceDebug includeExceptionDetailInFaults="true"/>的设置,服务端的异常是无法抛到客户端的。但是在正式环境中,不可能对进行serviceDebug的配置。正确的处理是在服务端对异常进行隐藏,替换,或者封装。

  比如我们在服务端捕获了一个已知异常,但是这个异常会暴露一些敏感的信息,所以我们对异常进行替换,抛出新的异常后,我们还要把这个异常怎样传输给客户端。首先们要明确WCF中的一些基本常识,就是WCF中的数据传递要遵循WCF的数据契约,服务端抛到客户端的异常(异常其实也是数据),所以必须要给异常定义异常契约。

    [DataContract(Name = "WCFException")]public class WCFException{[DataMember(Name = "Type")]public String Type { get; set; }[DataMember(Name = "StackTrace")]public String StackTrace { get; set; }[DataMember(Name = "Message")]public String Message { get; set; }}

然后处理异常的公共方法改写为:

public static bool Execute(Action action)
{try{action.Invoke();return true;}catch (Exception ex){//1,异常隐藏//2,异常替换//3,异常封装//写日志WCFException exception = new WCFException{Type = "Error",StackTrace = ex.StackTrace,Message = ex.Message};throw new FaultException<WCFException>(exception, new FaultReason("服务端异常:" + ex.Message), new FaultCode(ex.TargetSite.Name));}finally{}
}

这样在服务端抛出的异常,就能在客户端捕捉到。现在是不是感觉自己又提升了一些,想成为编程高手是指日可待了。

四:举一反三

  异常的处理也不过如此,那是不是应该举一反三,看看事务的处理应该怎么办?比如现在大量的访求都用到了事务,如下代码:

public Boolean Save(AccountModel accountData)
{OracleConnection conn = new OracleConnection("连接字符串");IDbTransaction trans = conn.BeginTransaction();Boolean result = false;try{//TODO ...
        trans.Commit();result = true;}catch{trans.Rollback();}finally{}return result;
}

特别是 trans.Commit();  trans.Rollback(); 这样的代码出现在每个与事务相关的方法中, 让我感觉到代码的臃肿,以及隐陷约约的失望。
经过我几天的翻阅资料终于实现了事务的公用访求提取。使用方法如下代码所示:

[TransactionAttribute]
[ExceptionAttribute]
public bool Save(DataContext dContext, Dictionary<string, string> dtoPara)
{Boolean returnVal = true;//TODO ...return returnVal;
}

就是在一个方法上加[TransactionAttribute]就表示这个方法写在了事务中,反之,不在事务中,加[ExceptionAttribute]就表示这个方法作了异常处理,反之,不作异常处理。通过反射或者AOP都能实现Attribute编程的效果。最后,还有什么疑惑,可以在评论中给我留言,当然别忘记了下方的【推荐】。

from: http://www.cnblogs.com/xcj26/p/3442089.html

精简自己20%的代码相关推荐

  1. 人脸检测算法代码python_Python有多强大!20行代码实现人脸检测与识别

    题记:大二的时候发现人生苦短,所以信了拍神,开始学Python.学了大半年之后成功转行做前端了.来写个教程帮助大家入门Python. Python优点 Python是一种简单易学.功能强大的编程语言, ...

  2. 20行代码发一篇NeurIPS:梯度共享已经不安全了

    整理 | 夕颜,Jane 出品 | AI科技大本营(ID:rgznai100) [导读]12 月 8 日-14 日,NeurIPS 2019 在加拿大温哥华举行,和往常一样,今年大会吸引了数万名专家参 ...

  3. php横排代码,20行代码原生js实现文字横向轮播

    20行代码实现文字横向轮播效果 1 页面布局代码 恭喜793765***获得 50元超市充值卡卡奖励 恭喜793765***获得 50元超市充值卡卡奖励 恭喜793765***获得 50元超市充值卡卡 ...

  4. 《看聊天记录都学不会C语言?太菜了吧》(14)这么神奇?我写了20行代码竟然一行就可以搞定?

    好消息2020年4月13日晚7.30我在CSDN开播,等你来聊天 预约连接:https://live.csdn.net/room/A757291228/MJWK0Gem 本系列文章将会以通俗易懂的对话 ...

  5. Python用20行代码实现一个验证码的输入与验证(完整源码)

    我们平常上网处处可见需要输入验证码的地方,利用Python的random()模块,其实我们只用简单20行代码就能实现.下为效果图,能识别是否正确: 其中也没有复杂的函数嵌套.函数递归,逻辑也比较简单, ...

  6. Python用20行代码实现完整邮件功能 [完整代码+建议收藏]

    大家好,我是Lex 喜欢欺负超人那个Lex 擅长领域:python开发.网络安全渗透.Windows域控Exchange架构 今日重点:python脚本实现发送邮件,邮件添加附件,读取接收邮件等功能. ...

  7. 女神相册密码忘记了,我只用Python写了20行代码

    ​视频地址 我用20行代码,帮女神破解相册密码 一.事情是这样的 今早上班,公司女神小姐姐说,她去年去三亚旅游的照片打不开了 好奇问了一下才知道. 原来是,她把照片压缩了,而且还加了密码. 但是密码不 ...

  8. python黑科技:Python大佬用20行代码带你打造一个微信聊天机器人,真神了~

    如何用20行Python代码打造一个微信群聊助手? 1.安装python环境 2.安装python的itchat库 3.安装itchat库 4.Linux 5.申请图灵机器人API和key 6.编写p ...

  9. C# 20行代码解析KRC歌词内容

    C# 20行代码解析KRC歌词内容 文章内容仅供学习参考,禁止转载. KRC 歌词文件支持了逐字精准,解决了一行歌词进度显示不准确的问题.由此好奇其存储歌词的方式,于是参考网络其他资料总结如下: KR ...

最新文章

  1. Android学习笔记21:ImageView获取网络图片
  2. android 反编译_Android 反编译实战
  3. 计量经济学建模_不了解计量经济学的前世今生,怎么能学会他
  4. Exadata上的分页查询性能测试
  5. Dapr牵手.NET学习笔记:状态管理之docker-compose发布
  6. 一句话概括4本管理著作
  7. python22个字符串长度_python字符串处理内置方法一览表
  8. 阿里如何做到百万量级硬件故障自愈?
  9. 数据加密密钥 分发_分发加密软件可能违反法律
  10. c mysql日期时间格式_[单选] 妊娠期血液成分发生改变,下述哪项是正确的()...
  11. Unity渐变色实现
  12. DevOps和持续交付
  13. 数学建模——stata基础操作
  14. 计算机过热保护,CPU过热 保护电脑关机的解决办法有哪些
  15. FPGA基础知识1(FPGA芯片结构)
  16. YUV编码为HEVC(H.265)
  17. java一维数组输入整数n_用键盘接受输入的整数,将输入的整数保存到一个一维数组,然后输出最大值...
  18. 通过网线连接获取树莓派的ip地址
  19. ORB-SLAM2系列第六章—— 跟踪线程
  20. 网传阿里裁员20% 涉及上万人

热门文章

  1. Java8 - 使用工厂方法 supplyAsync创建 CompletableFuture
  2. Centos显示-bash-4.1$问题的修复及原因探究
  3. 杜克大学计算机科学专业,杜克大学计算机科学专业研究生留学申请条件高不高?...
  4. springboot+mybatis测试时遇到java.lang.NullPointerException
  5. python知识:string.format()函数详解
  6. (04741)计算机网络原理,04741计算机网络原理真题_成都英才教育网
  7. php数组保存txt,php将数组存储为文本文件方法汇总,_PHP教程
  8. python判断数组中是否存在重复元素_利用python查看数组中的所有元素是否相同
  9. native字体尺寸自适应 react_react-native中 屏幕以及字体 大小适配
  10. .dat数据文件怎么打开_U盘坏了怎么恢复数据?恢复数据的方法