欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

异常、业务状态码、错误码的使用分析

程序员文章站 2022-04-17 18:55:34
...
http://www.iteye.com/topic/1112683
好吧,看了各位的发言,我突然觉的自己蛋疼了,我的公司也蛋疼了。
不过可别说我经历的项目初级。
从日pv超百万的论坛和价值几亿的银行项目我都经历过。现在我经历的最大项目,整个工程都将近2g了。
从几个人的小项目到几百人的项目我都有经历,不过都没有用异常控制业务子流程的,甚至我现在的公司在代码规范里面都严格禁止了使用异常做业务子流程控制。

之前我列出两种实现新增记录的方式,都是指分别在有惟一键和没有惟一键的情况下说的,我并没有说一定不要用哪种方式,一定要用哪种方式。只是要根据实际情况选择。如果数据表里面就是没有建惟一索引你怎么办呢?有时候你的选择余地很小,并不是自己想怎样就能怎样,也并不是自己认为哪种方式好就能用哪种方式,甚至也不是业内公认的哪种方式好就能用哪种方式。难道要求采用的那种方式你认为不好,你还不干了吗?当然只是举例代码,没有考虑更多可能。另一方面确实很多教材都不建议自己维护数据一致性,之所以这么要求是因为这么做对程序员水平要求很高;但是并不是完全禁止这么做。自己用程序实现维护数据一致性,极大程度降低了数据库压力,这是自实现维护数据一致性的优势。

曾看过有老外写的书,建议设计数据表的时候采用惟一键做主键;书里的意思就是像用户表这一类表就用不能重复的用户名做主键,但是数据量一旦超50000,字符串查询效率就会明显降低了,而使用主键查询是最频繁的。考虑到分表的情况,动辙十几万到上亿的记录,你要分多少表?更何况谁见过哪家博客的url里面出现过用户名。我想iteye博客的url那一串数字一定博主的用户名主键。

有同学说异常能包含更丰富的信息,这倒是不假,抛出异常能更有效更快速的定位问题和对非正常情况做出简单明了的说明。不过我始终认为异常就是用来指示程序运行的非正常情况的,而不是用来参与程序运行的正常流程的。
比如说登录用户不存在,密码错误,新注册用户名已被注册等是程序运行时的正常业务情况,不应该用异常处理。网络连接断开,数据库连接断了,违反数据约束了,本来应该存在的文件却没找到,本来应该存在的引用却是null,传递了错误的参数类型或错误的参数数量,这是非正常情况应该用异常。不知诸位注意过没有,在jdk里面状态码和异常是都有定义的,难道大家平时只注意到异常,没意识到jdk里面还定义了状态码和标识码?
至于究竟是用数据库自身的机制维护数据一致性还是自己实现,我明晚另开新帖再说吧,毕竟这个问题偏离了这个帖的主题。顺便在新帖介绍下我看过的一篇介绍ebay架构的文章。人家用不用数据库约束维护数据一致性,和dba有什么关系?人家的dba肯定很牛,只是架构设计是那样的。谷歌的搜索引擎还是自己实现的数据存储算法和文件系统,它内部的一些管理功能只用的mysql,难道你要说谷歌用不起商业数据库吗?我现在的一个同事,他以前的一家公司嫌数据库太慢,完全用c++实现的操作文件系统和磁盘阵列,用来存储和读取数据;用算法立即定位到要读写指定硬盘、指定磁道、指定扇区,连解析sql的时间都省了。难道你要说那家公司连数据库都不会用?当然这是针对特定领域的优化实现,我同事的上家公司不在意数据一致性和安全性,所以可以那么做。搜索引擎更多考虑搜索有效性,即使某些页面的数据没有了还可以重新用蜘蛛机器人爬到,还可以通过增加备份提高数据安全性。数据库更多考虑通用性和低成本可维护性。

至于究竟是采用业务码和异常来处理业务子流程。个人并不喜欢使用异常来处理子流程。以前我也用异常处理过子流程,后来觉的麻烦,每个子流程都要创建一个新的类,而业务一旦确定了,能发生的情况是极有限的,用业务编码或枚举能很容易的穷举出来。况且你难道连自己要用程序处理的业务有多少子流程都不清楚?即使抛开效率问题不谈,这难道不是最简单的方式?只是用于业务子流程之间的跳转,只是不同状态之间的转换,你还需要跳转的时候传递多少信息?
处理有多种状态的业务流程的时候,简单的情况可以使用业务状态码、枚举;复杂一点的可以使用状态模式,再复杂的可以使用工作流引擎,再复杂的可以使用有限状态机。不论是业务的可扩展性、可维护性和降低耦合、提高内聚,都比使用异常要好的多。

至于errorcode是用在出现了非正常情况的,这种时候用异常当然更方便些,也更容易标识出了哪类错误。这个时候使用错误码和枚举来标识非正常情况,自然有些捉襟见肘。我个人也喜欢使用异常处理非正常情况。但是在某些极端情况,比如系统资源极端紧张的环境下使用错误码显然是更好的选择。究竟使用什么,得视具体情况而定,并不能一概而论。不知回帖的各位有多少看过《代码大全》这本书。里面讲过业务状态码、错误码和异常究竟该在什么情况下使用。尽管书已经有些年头了,但是个人认为里面的观点并没有随着时间而老化。

最后再说一点,如果你实现的业务里面有众多业务子流程还有可能因为各种原因抛出不同的异常;如果要用异常处理业务子流程,那么就必然会把正常的业务子流程和各种非正常情况都用异常处理了。在这种时候你还能分的清哪些是为处理非正常情况自定义的异常,哪些是为处理业务子流程定义的异常?使用异常处理业务子流程就一定能保证稳定性和可维护性吗?一堆try catch你不觉的乱吗?从多个异常里面理清哪些是处理业务的异常,哪些是处理非正常情况的异常才会让人生不如死。使用业务状态码或枚举难道可维护性和稳定性就差吗?如果你对枚举很熟你会发现它是个很好用的东西,现在我就觉的它就是为处理各种不同状态而生的,你甚至可以借助枚举针对特定业务应用状态模式,而且我已经借助枚举实现了一个处理特定业务的流水线模式。如果你去阅读下状态机、工作流引擎的源码,想信你一定不会看到有用异常处理子流程和各种状态的情况。它们得为通用性考虑,即然通用情况下能不用异常处理,而且能工作的很好,很方便开发。相信在特定情况下也能一样工作的很好,很方便开发。也不会让人觉的不用异常会让人生不如死。

让各种技术和语法特性去处理它们该处理的,拿个扳手拧螺丝不觉的工具不合适吗?难道你没有更合适的工具?