假如代码规范是法律你可能还缺代码道德

一般来说,代码规范是一个企业每个开发人员都必须遵循的规定,发布前会有统一代码自动检测,违反任何一条都不允许发布。个人认为,开发人员除了要遵循这些硬性规定,平常也应该要有良好的偏软性的代码习惯,就像生活中除了法律还有大家都崇尚的道德一样。两者的出发点都是为了确保更高的代码质量,只是有些规定不好自动化或者没有被考虑到,就只能作为一个良好的代码习惯存在着。Code Review阶段是审查代码习惯的一个好时机。下面罗列一下我自己在工作中总结的十几条比较好的代码习惯:

  1. 不涉及数据库查询的参数校验或参数修正,应该停留在controller层,只有涉及数据库查询的校验才可以放到service层(比如数据查重)。这样可以保持service层逻辑的整洁,避免被一大堆的校验代码污染可读性,同时清晰的代码责任分离有助于更快定位问题代码的位置。校验建议最好都使用注解或自定义注解。不过目前hibernate-validator的自定义注解写法实在丑陋,不易读不易维护不易复用,还不如直接在dto上直接写个validate的方法来的简单直接。

  2. 对entity的处理应该在entity中封装对应的构造方法或create方法或edit方法来处理,不应一大坨代码放在service。有些杠精可能会说应该避免充血模型,贫血模型才是正道,额,概念我不是特别懂,反正这些模型概念被创造出来就是为了更整洁可维护的代码,过分强调某个模型多少有点过度设计的味道,这里只会把entity的创建编辑等只针对当前entity的操作封装在里面,不涉及其他逻辑,方法也不会定义很多,足够简单,何乐而不为。

  3. 一个复杂方法的实现,看起来应该像一个大纲一样,第一步做什么,第二步做什么,第三步做什么,每一步基本应该只需要一两行代码完成,复杂方法(尤其是service层的方法)中不应该有每一步的具体逻辑,具体逻辑应该另外封装方法,如果另外封装的方法也较为复杂,应该再进一步列大纲分步封装方法。封装方法时,要考虑好方法应该放在什么位置,过多的在一个类中封装private方法也容易导致代码显得杂乱无章,这时候可能单独针对较为复杂的业务逻辑相关的方法抽离到一个辅助类中。

  4. 底层方法签名要尽可能通用,比如service,dao层的方法要尽量考虑复用,避免使用DTO复杂类型作为参数,避免使用Result这种接口规范响应参数或者VO作为返回值,避免使用Map/JsonObject这种字段不清晰的结构作为参数或返回值。当然个别情况无法避免,比如创建,编辑时参数过多,只能使用DTO,又比如service的返回是分页的结果,只能用Page包装等。但对于比如queryById等这种入参和出参可以定义成简单形式的应该保留简单形式,在controller层再进行Result的包装,尽管这个方法暂时没有被复用,也应该遵循这个原则。

  5. 尽管业务上规定有些情况可以写死,也应该考虑写死的位置应该尽可能保证影响最小化。比如实现通过页面创建数据库的功能是,业务规定建索引只能所以其他表的id,在对索引的数据建模时,应考虑按照通俗理解去定义索引的数据模型,在校验层去限制只能索引id字段,这样如果将来有变,也只需要放开校验即可,而且按照通俗理解的去定义,别人一看就能看明白。当然也要衡量这么做的工作量,如果额外工作量过大就没必要了。

  6. 善用通用工具类的封装去避免业务代码的啰唆,除了常规的各种StringUtils, CollectionUtils,在业务代码实现时也可考虑自行封装。比如分布式锁的try catch finally块就很啰唆,可以考虑使用Runnable把try catch finally搬到通用方法中,调用时只需传递Runnable参数即可。

  7. 针对每个提供的http接口,要清晰地定义接口的入参DTO和出参VO,维护好swagger,尽量避免使用Map/JsonObject,不应直接使用entity,也不要轻易复用DTO/VO,除非是完全一样的参数才可考虑复用,否则都很容易混乱,后期很难维护。

  8. 尽量避免在当前entityService写其他entity的数据库逻辑,其他entity的逻辑应该写到它所属的service中,通过注入该service类进行调用。

  9. 复杂逻辑一定要多写注释,review代码发现自己都看不懂时一定要及时补上注释。

  10. 单元测试,应该避免依赖数据库已存在的数据,以及跑完之后残留脏数据的情况。具体可以考虑封装相应的工具类,使用@Before在测试方法之前插入所需数据,通过@After或者spring生命周期的destroy方法删掉过程中创建的数据。比较好一点的方案是使用mybatis拦截器来收集过程中插入的数据以便删除。另外,插入的数据可以作特殊处理,比如对于自动生成的id加上某个固定的前缀,万一数据没有成功清理时可以比较轻易地手动清理。

  11. 写代码时尽可能以最直观的方式去实现,避免因为遇到困难而选择一些曲折的方案,这样会导致代码可读性差,维护难度大。遇到问题不要绕行,要弄清楚为什么会有问题,能否解决,不能解决的情况下再考虑使用其他方案,并做好注释。

  12. 遇到某些难以定位的bug时,不要乱,要善用排除法,比如先将代码恢复到正常的时间节点,然后一点一点的增加后来修改的逻辑,逐步定位到出问题的大概位置(比如WebConfigurer问题定位)。

  13. 虽然通常代码规范限制嵌套不能超过3层,而且有些大括号块还不算嵌套,比如try catch,但我个人觉得,3层就已经很丑了,应该尽量确保在一个方法内最多2层大括号嵌套,嵌套的代码可读性实在很差,能封装方法就封装方法。

软性规范,见仁见智,欢迎谈论。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容