code S: code style & code standard

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 关于代码风格与代码规范的二三事

先解释一下标题, 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
  • 数据结构上要考虑功能将来的扩展

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

工具类规范

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

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

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

抽象封装 / 参数优化

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
敏捷开发 Dubbo Java
需求开发人日评估
随着敏捷开发在国内的风靡,越来越多的团队开始推行敏捷开发,这其中有一个关键事项就是:工时的人日评估。简单来说就是:项目经理会让开发人员自己评估自己负责的模块大概需要的开发周期。 人日,即按照1人几天完成,如1/人日:表示这个需求需要1个人1天完成,如果有2个人一起做,可能就是0.5天(需求开发一般1+1 < 2,因为有代码合并的兼容性要处理)。
1026 1
|
9月前
|
域名解析 网络协议 测试技术
[插件使用] SwitchHosts自动更新Github Hosts文件
[插件使用] SwitchHosts自动更新Github Hosts文件
1902 0
|
存储 消息中间件 缓存
相比游戏客户端,游戏服务端开发无关紧要吗
感觉游戏服务端,除了更新,保存数据啊、生成随机物品啊、都没什么了,好像游戏开发场景中,服务端已经无关紧要了。看着客户端忙成狗,正在摸鱼的你是否也有过这样的疑问?
660 0
相比游戏客户端,游戏服务端开发无关紧要吗
|
7月前
|
Oracle Java 关系型数据库
Java中的编码规范与代码审查实践
Java中的编码规范与代码审查实践
|
9月前
|
存储 缓存 网络协议
【专栏】理解并优化DNS设置对于提高网络速度至关重要
【4月更文挑战第28天】本文探讨了DNS服务器是否能加快网络访问速度。DNS负责将域名转换为IP地址,其查询时间、缓存机制和地理位置都影响网络速度。优化DNS配置,如选择快速的公共DNS服务、使用附近的服务器、确保设备正确配置和利用DNS缓存,都能有效提升网络体验。理解并优化DNS设置对于提高网络速度至关重要。
1380 2
|
9月前
|
Java 微服务
skywalking全链路追踪
skywalking全链路追踪
|
Java Maven 数据库
如何用 APT(Annotation Processing Tool)自动生成代码
如何用 APT(Annotation Processing Tool)自动生成代码
273 0
|
存储 索引 Windows
bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等
bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等
2193 1
bmp位图格式详细介绍-1/4/8/16/24/32bit、存储格式等
|
存储 Web App开发 运维
一种业务中台建设的方法
## 一、中台建设的复杂性 ### 1.1 中心、平台、中台的演进 应用架构一般演进的规律是,从中心应用演进成平台应用,然后从平台应用演进成中台应用,演进背后的底层逻辑就是"降本增效",降本增效在软件架构中经常被提到,本是成本的意思,效是效率的意思,连起来就是降低成本提升效率,仅仅回答到这一层,还是有些抽象,这里"本"包含了哪些成本?"效"又包含了哪些效率? 软件开发的成本包含了:分析成本、沟通
2191 0
一种业务中台建设的方法
|
安全 架构师 前端开发
五级QA工程师&能力模型
阿里QA导读:魔幻的2022即将在一片咩咩咩声中收尾,很多小伙伴此时可能都在居家办公,或者免疫系统还在跟病毒大战,当然还有天选打工人依旧奋斗在办公室,不管现在处于哪种情况,紧张而又忙碌的一年马上就要结束了,是时候捋一捋这一年的成长和收获,好好做份总结了。作为一名QA工程师,总结之前,我可能会先回顾一下这些问题:这一年我在哪些项目中大放异彩,又做了哪些质量建设呢?怎么才算是一个优秀的QA工程师?未来哪些能力需要补齐或精进呢?本文就QA的未来价值空间和职业发展的思考,抛砖引玉,期望多多交流~
617 0
五级QA工程师&能力模型

热门文章

最新文章