工作三年后, 我作为Java后端开发的一些心得
关于开发
敢于和善于使用package
- 对于Java后端开发来讲, 在长时间的web开发中. 大家已经熟悉了MVC架构, 也被这套结构所束缚. 导致创建出来的包也一直都是controller, manager, service, dao. 也将各种各样的类文件都放入其中. 这并不是一种好的做法.
- 其实我们可以大胆的创建相关的package, 只要让结构更合理, 可读性更高.
- 比如可以把对接前端的类写到request, response包; 把一些处理器提取出来放到handler中, 把一些定时任务放到schedule包; 把参数构造相关的放到generator; 把校验相关的放到validator下等等.
合理的提取业务逻辑, 让方法只做和它相关的事情.
-
不知道大家是否看到过下面这种代码. 例如在一个单据的创建方法中, 做一系列的事情, 比如一坨校验参数逻辑, 一堆取价逻辑, 一堆扣减库存逻辑, 再加上创建单据本身的逻辑. 写下来一个方法上百行不止.
-
public class OrderManager { @Autowired private OrderService orderService; public String createOrder(Request request){ // 1. 检查单据创建参数是否合法 if(Objects.isNull(request)) { throw ....; } if(CollectionUtils.isEmpty(request.getGoodsList())){ throw ...; } ... // 获取商品的价格 List<Goods> goodsList = request.getGoods(); goodsList.forEach(goods -> { // 查询商品价格 // 校验价格 // 对价格进行填充 }); // 构造单据逻辑 // 创建单据 return orderCode; } }
-
这个方法里做的事, 没有多余的事情, 但是没有合理的进行业务逻辑的提取. 导致代码看起来非常的杂乱.我们可以对一些业务逻辑做提取封装. 来的到更好的可读性和解耦. 这只是一个简单的例子, 在复杂的业务逻辑里更需要合理提取, 否则屎山就出现了.
-
public class OrderManager { @Autowired private OrderService orderService; @Autowired private OrderValidator orderValidator; @Autowired private OrderGenerator orderGenerator; @Autowired private PriceService priceService; @Autowired private InventoryService inventoryService; public String createOrder(Request request){ // 1. 检查单据创建参数是否合法 this.orderValidator(request); // 获取商品的价格 this.priceService(request.getGoods()); // 构造单据逻辑 Order order = this.orderGenerator.generator(request); // 创建单据 this.orderService.create(order); return order.getOrderCode(); } }
合理的方法命名和方法定义
-
方法名的定义很令人苦恼, 常常思前想后想不到好名字. 我曾经因为方法命名不好, 被疯狂的comments
-
方法命名的好坏受个人主观影响, 所以只说几个共同点:
- 言简意赅 准确表达方法内容
- 方法名与方法内容匹配
- 尽量别生僻单词…
-
对于方法的参数, 参数过多的时候, 对方法进行拆解或者抽象出对象去传参:
-
// 错误的案例 public int setParam(int xxx, String xxx, String xxx, String xxx, String xxx, int xxx, String xxx, String xxx){ ... } // 合理的写法 public int setParam(XxxRequest request) { }
控制方法的圈复杂度, 让代码更有层次感
-
我一直觉得, 好的代码读起来应该像故事一样, 有前因, 有后果, 中间娓娓道来. 简单举个例子, 我们可能会遇到在方法中去for循环处理数据的情况. 比如在一个方法中, 套了三层循环.
-
List<String> orderCodeList = request.getOrderCodes(); // 第一层循环 for(String orderCode : orderCodeList){ // 查询单号对应的单据明细 List<OrderItem> items = this.orderItemService.getByCode(orderCode); // 第二层循环 for(OrderItem item : items) { // 执行操作1 // 执行操作2 // 执行操作3 // 第三层循环 for() } }
-
可以把每一层for循环都提取出来, 成为单独的一个方法, 来降低圈复杂度, 提高可读性
-
List<String> orderCodeList = request.getOrderCodes(); // 第一层循环 for(String orderCode : orderCodeList){ this.processSingleOrder(orderCode); } public void processSingleOrder(String orderCode){ // 查询单号对应的单据明细 List<OrderItem> items = this.orderItemService.getByCode(orderCode); this.processItemsData(items); } public void processItemsData(){ for(OrderItem item : items) { // 执行操作1 // 执行操作2 // 执行操作3 } }
不知道的知识可以去问问Google, 不要自己编
-
不知道标题是否贴切, 但是大家看了例子就会明白我的意思.
-
其中最为典型的例子我认为 是对Obejct和集合的判空 和 创建集合
-
// 对于判断, 很多人喜欢这样写 if( list == null || list.size == 0) 或者 if(order == null) // 对于创建集合, 去创建空集合, 再添加 List<String> list = new ArrList(); list.add("xxx"); list.add("bbb");
-
其实只要我们Google以下, Java下如何对集合判空, 就能看到apache.commons 或者google.common等很多类库已经包含这些内容, 并且实现的更严谨, 更优美. 要请善于使用搜索引擎去填补自己不了解的知识.
-
CollectionUtils.isEmpty(list); List<String> list = Lists.newArrayList("xxx", "bbb");
不要for循环请求数据库和外部系统接口
- 慢请求的分析, 可能不需要要先去看有没有复杂的关联查询, 或者是不是数据库查询有没有命中索引, 而是先去看是不是有大哥在for循环去请求数据库和dubbo接口. 循环了1w次. 我曾经遇到过多次请求超时都是因为有人在代码里for循环去select , update.
- 对于这种问题的解决, 将循环调用改成单次的批量接口就可以解决问题. 对于mysql的化in操作就可以解决, 对于外部系统对接的, 双方提供批量接口就可以了.
没有意义的注释不要写
-
我很反感在类上要先写上 @Author @Date @Description 一大串内容表明这是你的杰作, 这不是JDK 也不是什么开源项目!!! 除了你和你的同事没人去看.
-
再或者像下面这样在方法上直白翻译了一堆废话, 注释不是这么用的…
-
/** * 查询用户名称 * * @Param name:用户名 * @Return 用户 */ public User getByName(String name);
不要忽视UnitTest
- 写过单元测试的会发现, 编写完善的单元测试会占用大量的时间, 一般都会超过需求的开发时间, 但是我还是认为单元测试是必须且重要的. 因为作为研发人员, 才是最了解代码中哪里容易出问题的. 更容易写出发现问题的测试用例. 并且代码迭代或者修改后, 也能更快速的发现问题, 将问题停留在研发阶段去解决, 提高整体的进度.
善于使用AI编程工具
- 在我使用了Github copilot和ChatGPT半年后, 我发现我的摸鱼时间变多了… 因为AI编程工具帮我完成了一定量的工作. 例如最常用的代码补全, 代码自动生成, 自动生成单元测试等等
- 在当今, 熟练掌握AI编程工具, 是提高自己工作效率的极佳的方法. 在未来, AI也一定会代替掉一部分程序员的工作.
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONbgJ6nV-1690847312973)(C:\Users\quyanliang\AppData\Roaming\Typora\typora-user-images\1690847111862.png)]
利用IDE的工具来完成代码和优化代码
-
IDEA自带功能扫描代码无用引用, 重复代码等坏味道 : Code → Inspect Code
SonarLint
MyBatis Plus
Lombok
Alibaba Java Coding Guidelines
CheckStyle-IDEA文章来源:https://www.toymoban.com/news/detail-638275.html
…文章来源地址https://www.toymoban.com/news/detail-638275.html
拥抱新技术
- 可能随着工作的时间变长, 大家对新鲜技术的兴趣并不像之前感兴趣. 或者认为目前的技术足够, 远不会过时, 即使过时了, 也会有公司使用.
- 技术是不断迭代更新的, 使用技术的人也要随之更新. 当大家都去开始了解和使用云服务, 容器化, 使用JDK 17的新特性, 开始用云原生框架去替换现有技术时, 咱总不能一直玩转jdk 1.8吧.
- 了解一些新技术并不是什么值得炫耀的, 不知道也不一定影响你工作和赚钱, 但是当互联网红利已经逐渐褪去, 内卷在越来越重的今天, 机会也变得弥足珍贵. 更好的知识储备, 也能让你能获得下一份工作, 在人才市场获得更多青睐.
- 我也一直认为, 开发对很多人来说不光是工作, 也有着一份热爱.
关于处理工作和人际关系
开发并不只是开发
- 这个标题就是字面意思, 指的并不是光顾忌自己的开发任务. 同时也要关注公司的运营和公司业务或者说自己负责的项目的业务.
- 我见过一些程序员只是单纯的根据产品的文档写需求, 你需求怎么写, 我功能就怎么写. 但是研发在看待需求时, 应该持有自己的见解, 观点和建议. 这也就是需求评审的目的.
- 不要觉得需求是产品提的, 和研发没有任何关系. 但是你需要考虑到, 当需求存在问题, 后续的需求优化, bug修复, 甚至数据处理, 可都是要由研发来做的. 简单来说, 错在产品, 但引发问题由你处理.
- 而公司的运营, 关系到了你在公司的生存和发展, 所以关注着公司的运营情况, 也大概你知道你明年的涨薪是否有希望, 年终奖是否能按时发放, 以及你是否应该考虑换一个公司去继续搬砖.
合理的分配和安排自己的工作
- 拿到需求不要急于开发, 不要急于开发, 不要急于开发.
- 我见过一些开发, 在拿到需求后会马不停蹄的开始Coding, 然后就出现边写边改, 再写又发现哪里存在问题, 最后发现写不通, 推翻了之前的结构再写.
- 这个可能并不适合所有人, 但是我认为在开始Coding之前, 是需要构思一下再着手的. 花一些时间分析一下这个需求, 考虑下设计到的各个部分, 构思下自己的开发思路, 设想下其中可能遇到的问题, 当思路清晰后, 再去着手开发, 这样会让你能够流畅的完成开发工作, 并且让你的代码质量更高.
对自己的工作要有Owner意识, 答应的事情要尽力去做到
- 什么是工作的Owner意识, 简单来说, 就是这个工作分配给你, 你就是第一负责人.
- 对于分配到自己手里的工作, 首先要有一个正确的评估. 可以简单的分为: 这个工作你能不能做, 能不能按时做完, 要怎么做, 最后能做到什么效果.
- 如果因为种种原因做不到, 需要提前预报风险, 不要等到最后一刻告诉大家, 你没做到. 任务分配给你, 是因为这是你的工作, 也有一部分信任在, 是相信你可以做好, 别去辜负别人的信任, 信任可能因为一件事就确立起来, 也可能因为一件事情就毁掉.
我不管别人摸鱼, 但不要影响到我的工作
- 工作难免偷懒, 大家都有想休息放松的时候. 我对这个事情的看法就是, 摸鱼可以, 但是不要影响别人的工作.
- 在整个项目或者需求的流程里, 产品, 后端开发, 前端开发, 测试人员都只是其中的一环. 对于各个环节的人员来说, 都是这样, 可以适当摸鱼, 但是不要压缩了别人安排好的时间.
自己的问题勇于承认, 但不是我的锅我不背
- 承认自己的问题并不是一个可耻的事情, 但是不承认被别人扒出来可是非常尴尬的.
- 如果你不能按时完成开发任务, 可以说明你的原因, 尽快的提出来, 别等到最后到了Deadline你说你做不完.
- 或者因为你的bug导致了线上事故, 也没必要遮遮掩掩. 快速的定位问题, 解决问题, 在会议上复盘问题, 最好下次发生同样的状况就好, 也没必要因此给自己很大的心理压力和负担. 常在河边走, 哪有不湿鞋.
- 但是, 对于甩锅这种问题, 没有人不反感. 我不去讨论什么叫甩锅, 我只去讨论怎么避免甩锅这种事情的发生.
- 在对于需求, 会议, 形成良好的书面文档, 各方进行确认
- 有问题避免天知地知你知我知, 有问题大家一起沟通, 沟通后形成相关的书面文档
- 当出现这种问题的时候, 拿出自己的证据来证明自己, 不是老子的锅老子不背
摆正自己和领导的位置
- 对于领导, 你是他的下属, 不管你们是酒友还是烟友或者是pao友, 你对他最重要的是工作的能力和处理问题的能力. 认真对待分配的任务, 做好自己的分内工作, 让他看到你对他在工作上的价值, 才是建立你们工作关系的基础.
合理的看待别人的反对和批评
- 可能每一个参加工作的人都被批评过或者吐槽, 被领导也好, 被同事也好. 在面对批评时, 不要急于反驳. 大家作为成年人, 很少会有人毫无原因和根据的前提下去吐槽你的问题.
- 他提出的问题, 可能就是你切实存在的问题, 他不说, 下一个人也会说, 尽早了解自己的问题并及时改掉不是坏事. 不能不在意, 也不要太在意.
如果你领导或者同事是sb
- 能忍忍, 不能忍就滚. 你不能强迫别人走, 你忍不了, 你自己走.
到了这里,关于工作三年后, 我作为Java后端开发的一些心得的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!