前言
关于异常处理,在网上的大部分博客大多关注编程语言本身的异常处理机制。而很少谈及在业务当中的实际应用情况。因而不是很能够get到其中的要点。这部分感觉只能自己多多思考和积累了。
最近在工作当中开发的一些基于Quartz任务调度实现的自动化功能,涉及到比较长的运行流程。包括hive数据的清洗导出,数据分包,打包成txt或者zip,多文件上传,自动重试。而每一个流程当中可能会出现诸多的异常,对应于多个运行的结果状态。
如何保证不管结果如何,到每一个流程运行完都能标记为正确的状态,并且可以通过结果来进行自动重试,最后能够将结果信息、错误信息返回到顶层?如何编码能够避免过多的if条件判断,拥有统一的编码风格?
查看了类似业务的编码,因为多状态的问题,代码判断很多导致可读性很差。对于多个渠道对应不同的上传预处理方式,直接判断处理导致代码更加臃肿。为此,我决定重构一下这块逻辑,以便更好的扩展和维护。
思路
首先,将所有可能出现的正常和异常情况列出来,然后归类,设计对应的枚举值。然后定义一个统一的处理结果类,如下:
1 | public class ResultInfo implements Serializable { |
2 | private static final long serialVersionUID = 1L; |
3 | //处理结果标记 |
4 | private boolean success = true; |
5 | //结果代码 |
6 | private String resultCode; |
7 | //存储的结果对象 |
8 | private Object model; |
9 | //返回信息,用于上层展示 |
10 | private String message; |
11 | //调用链存储结果对象 |
12 | private Map<String, Object> map = new LinkedHashMap<String, Object>(); |
13 | //调用链存储错误信息 |
14 | private Map<String, String> errorMessages = new LinkedHashMap<String, String>(); |
15 | } |
接下来,我们所有的业务处理正常返回的数据都存储到这个结果对象当中。或者定义一个统一的业务异常类来集中处理。对于具体的异常处理,我们用try catch捕获,对于底层的就通过结果对象往上层调用传。在上层业务通过取结果对象当中的代码或者错误消息还有返回数据对象等等来统一处理当前业务的状态变更,而不在下层处理导致底层模块以来上层业务。
对于底层异常来说,因为比较独立。例如文件的打包等等,我们就没必要做统一异常的处理。这个时候用throws 往上层抛出,上层接受后在统一处理。另外对于并发锁的部分我们要在finally当中单独进行处理。
关于不同渠道的文件上传,因为有不同的数据预处理方式,走的接口也是完全不一样的,没有办法统一,但是它们在抽象上都属于上传这个领域。因此,我考虑使用工厂模式来组织代码。在服务层,依赖于工厂和上传接口。而工厂去生产具体的上传服务,各渠道服务实现抽象上传接口。从而实现这部分引起的业务逻辑判断过多的问题。
踩坑总结
具体的实现过程当中,还是发现因为判断多而思路不清晰的时候。不过当我把业务拆解到更细粒度的方法的时候就变的清晰很多了。很重要的经验:先处理异常情况,最后在处理正常情况
虽然是日常编码中很小的点,但是正是这些小地方让代码变得更优雅。争哥的设计模式课程的学习,给到我很大的看见,继续加油Storm。