code S| 关于代码风格与代码规范的二三事

date: 2017-12-19 14:07:34
title: code S: code style & code standard
description: 关于代码风格与代码规范的二三事

先解释一下标题, code S 既可以是 code style, 也可以是 code standard, 大部分情况是兼而有之. 无论是 style 来表达 编程之美 或者 编程即艺术, 还是用 standard 来 约束, 都表达了 code 应该是 有迹可循 的.

关于 code S 这个话题, 一个相关的是最近很火的 阿里巴巴 Java 开发手册. 作为 phper, 自然是 PSR. 另一个值得推荐的是 程序员DD - 翟永超的公众号 中的专题文章 -- 程序员你为什么那么累.

本篇参考了大部分 程序员DD - 翟永超的公众号 中的文章, 推荐移步一观.

首先是需要考虑的几个问题:

是不是觉得很矛盾, 一方面工作不复杂, 一方面却累成狗
大部分人的大部分时间都是在 定位问题 + 改代码, 真正开发的时间并不多
simple is not easy
对于个人来说, 技术很重要. 但是对于工作来说, 编码的习惯比技术更加主要
不管接手任何项目组, 第一步就是制定代码框架, 制定项目组的开发规范, 把代码量减下去

对比:

原始
规范后

这样做的思想也很简单: 实际上干活的就只有一行, 其他都和业务代码没有一毛钱关系.

实际效果也很明显: 代码量减少 -> 加班减少 -> 我愿意

PS: 技术精简使用的 AOP, 其中 Lang 会使用 ThreadLocal 处理掉.

详细议题:

  • 接口定义规范
  • controller规范
  • 日志规范
  • 异常处理规范
  • 国际化规范
  • 参数校验规范
  • 工具类规范
  • 函数编写建议
  • 配置建议

规范里面大部分是 不要做的项多, 要做的比较少, 落地比较容易
代码最主要的不是性能,而是可读性, 有了可读性才有维护性
我觉得我的编码习惯比技术更有价值
傻瓜都能写出计算机可以读懂的代码, 只有优秀的程序员才能写出人能读懂的代码

程序猿不招妹子们喜爱的根本原因在于追求了错误的目标:更短、更小、更快。

接口定义规范

  • 返回格式统一, 不要使用 map,json,object 等类型, 统一使用 ResultBean / PageResultBean
  • 考虑失败情况: 被 ResultBean 封装掉
  • 出现业务无关输入参数, 比如上面的 Lang 使用 ThreadLocal 优化掉
  • 出现复杂输入参数, 比如 json, 可读性极差, 应该定义为对应的 bean
  • 没有返回应该返回的数据, 这需要编程经验, 不返回或者返回True 都是不应该的. 别人要不要是别人的事情, 你该返回的还是应该返回

ResultBean: code(状态) + msg, 并处理 Exception

统一的好处:

  • 避免很多无用返工和可能出现的问题
  • 代码可读性
  • 利于利用 AOP/自动化测试这些额外工作

controller规范

上面的规范要继承, 还需要注意以下几点

  • ResultBean/PageResultBean 是 controller 专用的, 不允许往后传
  • Controller 做参数格式的转换, 不允许把 json/map 这类对象传到 services 去, 也不允许 services 返回 json/map
  • 参数中一般情况不允许出现 Request/Response 这些对象
  • 不需要打印日志 -> AOP, 大部分日志 Service 层打印

json/map, 格式灵活, 但是可读性差 -> bean, 看着工作量多了, 但代码清晰多了

AOP:

  • 打印日志
  • 捕获异常, 异常分为已知异常和未知异常, 未知异常添加邮件通知之类的, 不同异常返回不同返回码
  • 配置 or 代码 -> 配置优先

日志规范

日志落地问题:

  • 没有日志功能一样跑 -> 出了问题没日志, 只能再加
  • 节点多 -> 日志要一个一个翻

日志至少要求:

  • 能找到机器
  • 能找到用户做了什么: log4j 使用 MDC 使日志记录是带上 user 标识
// nginx -> 简单配置返回节点
add_header X-Slave $upstream_addr;

打印日志要求:

  • 修改操作必须打上日志
  • 条件分支必须打上条件值, 重要参数必须打印
  • 数据量大必须打印数据数量

培养日志习惯:

  • 不要依赖 debug, 多依赖日志
  • 代码提交前先跑一遍看看日志是否看得懂

日志等级 -> 不是很关注 -> 简单规则, 更好落实

异常处理规范

出了异常不知道 -> 闹大了被投诉
出了问题无法定位原因
任何规定都无法保证一定不会发生错误 -> 我只相信代码

  • 开发组长定义好异常, 其实没几种, 太细了很难落地
  • 绝大部分场景, 不允许捕获异常, 不要乱加空判断 -> 自以为写了 「健壮」 的代码 -> 尽早让错误抛出来
  • 后台(任务队列)异常一定要加通知机制, 要第一时间知道异常

国际化规范 & 参数校验规范

  • 业务代码里面不要出现和业务无关的东西, 如 local/MessageSource -> ThreadLocal
  • 国际化信息放哪: url vs cookie -> url 比较 low 还容易出问题
  • 静态方法注入实现参数校验
  • 参数非法时打印 key/value 出来

PS: 代码写得不够好, 才需要多加注释来凑

工具类规范 - 动态代理

  • 定义注解 -> 需要常驻内存支持, 不然每次运行都需要消耗性能来解析注解
  • 注解解析 -> Reflections -> 生成动态代理
  • 动态代理 -> 注册到 spring 容器
  • 定义默认的 RestTemplate 处理请求类 -> 注册到 spring 容器 -> RestTemplate 可以添加认证
  • JUNIT 测试

函数编写建议

  • 不要出现业务无关参数
  • 避免使用 Map/Json 等复杂数据结构对象作为参数和结果
  • 有明确的输入输出和方法名
  • 把可能变化的地方封装成函数 -> 需求老变
  • 编写能测试的函数

配置规范

  • 先定义 bean -> 确定包含关系
  • 使用代码生成 + 测试
  • 业务开发 / 功能测试完毕 -> 定义配置文件, 格式推荐 JSON

禁忌:

  • 读取配置和业务代码耦合
  • 开发初期就定配置文件

应对需求变更

说的好像别人的需求就不会变动似的
正是因为需求变更不可避免, 所以我们才更应该把代码写简单, 以对付各种各样的需求变化

  • 把代码写到最简单
  • 把可能变化的封装成函数
  • 多个功能中先做不会变的功能, 一个功能中先做不会变的部分
  • 设计上多采取解耦的设计, 多引入「第三者」, 不要直接发生关系 -> IOC
  • 数据结构上要考虑功能将来的扩展

要主动思考, 多走一步, 不要被动接受看到的需求, 要对需求的将来变化做好心中有数

工具类规范

定义自己的工具类, 尽量不要在业务代码里面直接调用第三方的工具类

  • 字符串处理: 判断字符串为空
  • 复制对象的属性和方法

抽象: 使用父类/接口
使用重载编写衍生函数组 -> 多参数数据类型
静态引入: 约定项目组使用的方法名
独立 / 框架级

抽象封装 / 参数优化

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,649评论 18 139
  • 文/山雨 又是一年,最起眼的是年龄改变。远处鞭炮声不断,像向世界宣告,任世事沧桑,任流年似水,人们一样活得精彩,命...
    如影泡幻阅读 236评论 0 2
  • 我们的俱乐部—双羽成立也快两年了,从最初的十几个人发展到今天的几十个人,年龄从二十来岁的年轻人到六十五岁的老...
    云淡风轻_d238阅读 1,107评论 0 3
  • 明天段子预告片《高冷女生与备胎》 高冷女生,一个神奇的物种; 备胎,另一个神奇的物种; 2015.3.25 com...
    迎刃阅读 436评论 0 2
  • 昨天,休息,好爽啊。于是乎,到电影院看电影。电影很好看,电影很抽象的,根本不现实的人物被拍得很厉害,很刺激。只不过...
    王玉笙阅读 93评论 0 0