目 录CONTENT

文章目录

如何让代码更优雅

路口、下车
2025-09-08 / 0 评论 / 0 点赞 / 10 阅读 / 0 字
温馨提示:
本文最后更新于2025-09-08,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

目标:提升代码可读性维护性扩展性,让自己的代码风格更优雅,代码质量更高。

Less coding, more thinking(少编码、多思考),Think more, code less(思考越多,编码越少)。

代码简洁之道(读书总结)

推荐:《代码简洁之道》(美)马丁(Martin,R.C.)著

第一章-整洁代码

1、为什么要写整洁的代码?(为什么)
因为糟糕复杂的代码,对系统的后续维护会造成很大的麻烦,甚至需要重构,使得生产力下降
读代码与写代码的时间比例为10:1,读代码的时间明显比写代码时间长,所以写好整洁的代码也会提高后续开发的效率。
复杂混乱的代码,会给后续开发者带来压力,没有精力进行维护和改造糟糕代码,甚至逼迫继续造成混乱,恶性循环

2、什么才算整洁的代码?(是什么)

  • 1)整洁的代码只做好一件事,一个方法、一个类只做自己的事(单一职责原则?避免受到四周细节干扰)
  • 2)减少重复代码
  • 3)便于后来者进行扩展、维护
  • 4)可读性强,读起来让人感到优雅、愉悦

3、这本书将告诉你大佬是怎么做的

  • 1)能通过所有测试

  • 2)没有重复代码

  • 3)提现系统中的全部设计理念

  • 4)包括尽量少的实体,比如类、方法、函数等

第二章-有意义的命名

一些命名的原则:

  • 1)名副其实通过命名能直接理解其意义,无需注释说明
  • 2)没有误导性,减少可能带来的误导性含义的命名
  • 3)要做好命名意义的区分,特别是使用相近的词汇时,减少废话如变量名带variable、表明代table、nameString代替name;
  • 4)命名最好能够读出来,不要自己造新词
  • 5)使用可以搜索的名称,比如一些常量,要定义MAX_CLASS_PERSON_NUM =10 而不是 a=10
  • 6)避免使用编码,徒然增加工作量,还要花时间解码
  • 7)避免思维映射,简单明确才是专业的
  • 8)类名要是名词、名词短语,避免使用Data、info、Manager这类词
  • 9)方法名要是动词或者动词短语
  • 10)别扮可爱、抖机灵,使用俗语或者俚语
  • 11)禁止使用双关
  • 12)一个抽象概念同一使用一个词,例如不要controller、Manager、driver混用表达一个抽象
  • 13)使用计算机专业术语
  • 14)给命名增加有用的语境,例如地址相关命名:name、addressName,state、addressState

第三章-函数

  • 1)单个函数简短,不宜过长
  • 2)一个函数只做一件事
  • 3)每个函数一个抽象层级,不要混合在一起同时处理不同抽象层面的逻辑
  • 4)Switch语句,一个类型一个操作,单一原则
  • 5)使用描述性名称,别害怕太长
  • 6)参数函数,能少就少
  • 7)一元函数的普遍形式,命名要规范
  • 8)最好不用标识参数,等于直接宣告破坏了单一职责原则
  • 9)二元函数最好能转为一元函数
  • 10)三元函数使得函数更加难懂复杂,要考虑清楚,如果参数过多,要考虑封装到一个对象中
  • 11)函数无副作用,校验的函数就只负责校验不要隐藏一些副功能,会导致一些时序的耦合,要么函数命名要声明出的副作用
  • 12)分隔指令和询问两个动作(一个函数要么做什么,要么回答什么)
  • 13)使用异常代替错误码
  • 14)抽离try{}catch{} 中正常流程函数和异常处理主体函数,使得代码正常流程和异常流程隔离开
  • 15)别重复使用相同代码,要抽取出一个函数
  • 16)结构化编程(每个函数只有一个入口和出口,意味着一个函数只有一个return,循环中不能有break\continue)
  • 17)如何写出好的函数(先写初稿,再按原则仔细打磨优化,配套单元测试保证优化后测试通过)

第四章-注释

  • 1)不要注释糟糕的代码,而是尽量地清理调,因为注释不会使代码变好!
  • 2)原则:最好用代码进行阐述清楚,一些能用好的命名解释函数功能或者参数就不需要用注释
  • 3)坏注释:
    • 1.喃喃自语。没有说清楚事情,而是按自己角度自说自话
    • 2.多余,没必要的注释
    • 3.误导性的注释,一定要把注释讲的清楚,不能带有歧义,让人误解
    • 4.日志式注释,已过时
    • 5.废话注释,比如一些变量名很清楚的,但还是加上了注释
    • 6.纯粹为了标记位置的注释
    • 7.注释代码的注释,请明确后主动清理无用的代码
    • 8.非公共代码中使用javadoc注释,难维护,也没有必要。
    • 9.短函数头加注释,实际上短的函数命名比注释重要的多,不是非常复杂的函数尽量使用命名表达清楚作用
  • 4)好注释:
    • 1.真正好的注释是不需要写注释(命名规范易懂、逻辑清晰)
    • 2.提供了基本信息的注释
    • 3.对意图解释的注释
    • 4.阐释的注释,特别是一些晦涩难明的参数或者函数(可能有阐释不明确的风险)
    • 5.警示类的注释,提示一些可能出现的后果,防止误删误改
    • 6.TODO类注释,是用来注释一些需要完善但未做的,但是一定要及时完成,定时查看。
    • 7.放大一些看起来不合理的代码,这么做的重要性。

第五章-格式

  • 1)格式的目的:一方面保证代码可读性、可维护性。另一方面,好的格式习惯哪怕代码重构或者被删除了,这些好的编程格式习惯也会跟随开发者本身。

  • 2)垂直格式

    • 1.向报纸学习 (大致意思:从头到尾要有大纲,有层次。由上至下,从高层次抽象再到细节,逐渐展开细节。
    • 2.不同概念、方法之间要由区隔。
    • 3.联系紧密的代码不要太多空白行和注释,让它们紧靠一起,看起来一览无余
    • 4.垂直距离:有联系的方法、函数尽量不要间隔太远,变量声明也是尽量要靠近引用的方法。但是也有例外,实体变量统一放在顶部是java开发的惯例,是开发者都清楚的共识。
    • 5.垂直顺序:一般而言,最好是被调用函数在执行调用的函数下面,这样能建立一个自顶向下贯穿代码文件的阅读模式。就像读报纸,从题目、大纲、再到细节
  • 3)横向格式
    参考:阿里java开发规范

第六章-对象和数据结构

  • 1)不要随意暴露数据实现和细节,最好以抽象形态向外表述暴露数据。对于一些复杂的数据接口不要未经思考随意使用赋值器或取值器
  • 2)对象和数据的之间的二分原理:过程式编程(一个类里兼容多套逻辑)、面向对象(利用抽象类,实现多态)
  • 3)Demeter定律:每个单元对于其他的单元只能拥有有限的知识:只是与当前单元紧密联系的单元;
    每个单元只能和它的朋友交谈:不能和陌生单元交谈;
    只和自己直接的朋友交谈。
  • 4)数据传输对象(DTO或者其他对象)不要包含业务规则,不要将他们和业务对象使用

第七章-错误处理

  • 1)使用异常而非返回码(标识):目前已没有这类错误处理方式,都是直接抛异常
  • 2)写try catch 处理异常,去处理可能抛出异常的代码。也方便TDD。
  • 3)使用不可控异常:可控异常回违法开闭原则,底层API抛出异常,那么上层调用都需要声明抛出该异常或者Try-catch该异常。(我们应该在什么时候使用可控异常Checked Exception呢?如果一个异常所表示的并不是代码本身的不足所导致的非正常状态,而是一系列应用本身也无法控制的情况,那么我们将需要使用Checked Exception)
  • 4)给出异常发生的环境说明:抛出异常要充分返回错误相关信息,打印日志方便定位问题
  • 5)依调用者需要定义异常类:将一些类A的方法可能抛出多种异常,通过封装一个打包类,统一捕获多种异常并翻译(避免每次调用A的方法需要重复catch 多种异常)。
  • 6)别返回null值。别传递null值。(很可能让调用者或者自己漏检查非空情况导致npe)

第八章-边界(软件边界)

  • 1)使用第三方代码,不要将一些API在封装类、近亲类之外传递,否则一旦api进行修改,会使得维护难度加大
  • 2)浏览和学习的边界:不需要把第三方的所有代码看懂,但是要为你写的代码编写测试对api进行一些了解。(进行学习性测试)
  • 3)使用尚且不存在的代码: 对外部依赖 进行多一层adapter处理。由adapter进行外部对接逻辑。那么可以先在进行内部逻辑编写和调试,等外部接口定义出来通过adapter进行处理就可以了。这样做也在系统之间多了一层隔离,方便正确的进行API的边界测试
  • 4)整洁的边界:封装第三方接口、或者使用adapter模式。这样维护号边界,第三方改动api时修改点也会少很多

第九章-单元测试

见“单元测试相关知识学习总结”

第十章-类

  • 1)类的组织:类由变量列表开始,从公共静态变量开始、再到私有静态变量、私有变量。公共函数再变量列表后,私有工具函数跟在调用的公共函数后面,这样符合自顶向下的原则。
    封装:尽量保护类的变量和函数的私有性。但如果测试需要访问,也可以放松封装,但这并不是好的做法
  • 2)类要尽量短小 :
    • 1.单一职责原则
    • 2.内聚:类应该只有少量实体变量。类的一个或多个变量被方法引用,变量越多被方法操作,越黏聚在类上。内聚性高,意味着类中的方法和变量互相依赖,互相结合成一个逻辑整体。但也不要一味追求高内聚。保持函数和参数列表短小的策略,有时会让一组子集方法用的实体变量数量增加。这样往往意味着至少有一个类要从大类中拆分出来。应该尝试拆分变量和方法到两个或多个类,使得新的类更为内聚
    • 3.保持内聚性会得到很多短小的类。将大函数进行拆分时,就是拆分大类成小类的时候。拆分完,职责和代码会更清晰
  • 3)为了修改而组织:在一个整洁的类里面进行修改肯定比在一个复杂冗余的类中修改更为简单。所以我们要保持类的简洁,需要持续对类进行组织。将公共的方法和私有的进行拆分,保持每个类的职责划分要清晰,这样修改起来,避免了修改一个类却要重新测试大范围的代码。

第十一章-系统

  • 1)将系统构造和使用分开

    • 1.分解main,将系统中的全部构造过程搬迁到main或者main模块中:main函数创建对象,再将对象传递给应用程序,应用程序只管使用,对构造一无所知;
    • 2.如果应用程序需要负责确定何时创建对象,可以创建抽象工厂,让应用程序控制实体创建的时机;
    • 3.依赖注入,控制反转IoC是依赖管理的手段,它将应用需要的依赖对象的创建权责从对象中拿出来,放在一个专注于此事的对象中,并通过依赖注入(赋值器)将依赖对象传递给应用;
    1. 扩容:面向方面编程(AOP),Java中三种方面和类似方面的机制:代理,纯AOP框架,AspectJ。

    • 1.java代理:适用于简单情况,如在单独对象或类中包装方法调用。代码量和复杂度是代理的两大弱点。
    • 2.纯Java AOP框架,如Spring AOP、JBoss AOP
    • 3.AspectJ:提供将方面作为模块构造处理支持的Java扩展
      最佳系统架构由模块化的关注面领域组成,每个关注面均用纯Java(或其他语言)对象实现。不同领域之间用最不具有侵害性的方面或类方面工具整合起来。这种架构能测试驱动,就像代码一样。

插件利用

合理利用idea插件,利用插件在提交代码之前提前检查代码规范和漏洞

阿里规约插件(Alibaba Java Coding Guidelines)

介绍

Alibaba Java Coding Guidelines 专注于Java代码规范,目的是让开发者更加方便、快速规范代码格式。该插件在扫描代码后,将不符合规约的代码按 Blocker、Critical、Major 三个等级显示出来,并且大部分可以自动修复,它还基于 Inspection 机制提供了实时检测功能,编写代码的同时也能快速发现问题所在。

阿里巴巴规约扫描包括:(1)OOP规约 (2)并发处理 (3)控制语句 (4)命名规约 (5)常量定义 (6)注释规范

安装

File > Settings > Plugins > Marketplace 搜索 “Alibaba Java Coding Guidelines”,按照提示进行安装,然后重启即可。

工具使用

  • (1)可以Tools > 阿里编码规约 > 编码规约扫描

  • (2)在编辑界面或者项目区域点击右键,在右键菜单中选择“编码规约扫描”即可

运行结果

扫描结果主要分三大类;Blocker(阻挡者)、Critical(严重问题)、Major(主要的),严重程度由高到低为:Blocker > Critical > Major

阿里格式化模板

描述

根据阿里规约制定的快捷格式化模板

阿里模板下载地址:https://github.com/alibaba/p3c/tree/master/p3c-formatter

安装

  • 1)下载阿里配置文件(eclipse-codestyle.xml),因为此文件是针对ecplice的,在IDEA中使用配置文件,需要安装Eclipse Code Formatter插件

  • 2)配置代码格式,File->Settings->Other Settings->Eclipse Code Formatter进行idea代码格式配置:将代码格式化文件eclipse-codestyle.xml,配置到插件中:

使用

快捷键:ctrl+alt+L

注释模板

统一类、实体、枚举 等新建文件的文件头注释信息

设置

设置fileheader.xml

/**
* ${description}
* @author kimli
* @date ${DATE} ${TIME}
*/
0

评论区