四年经验老开发,总结的Java代码规范全部奉上。

写代码就像写文章, 好的代码就像好的文章,结构严谨,构思清晰。写代码就像写文章, 一不留神就成流水账,为避免这种情况作为软件开发工程师,重要的是设计而不是实现。

在一个团队中,由于不同经验的开发导致编程风格可能会出现非常混乱的情况,从而导致开发成本上升。难以维护。所以代码规范就显得异常重要了。

本篇文章就是给出编程命名的建议,仅供参考,但是其目的是为了统一规范,提高编程能力,降低开发成本,减少代码维护成本。

契约精神: 做到有法可依,有章可循。

一、类命名

1. 抽象类

适用的设计模式为模板模式。抽象是自下往上的设计。由具体实现推断出抽象方法。建议以Abstract开头。

建议示例
Abstract 或者 Base 开头BaseUserService、AbstractUserService

2. 枚举类

  • 枚举是由JVM来保证的单例。可以用来做单例类。
  • 枚举类常用作值判断,不建议每次进行循环判断得到实例。建议由内部维护一个map类型,当做cache。此方法建议放在static静态代码块中实现
建议示例
Enum 作为后缀GenderEnum
public enum ProtocolEnum {

    /**
     * ECHO协议
     */
    ECHO(1, null),

    /**
     * mojito协议
     */
    MOJITO(2, MojitoProtocol.class);

    private byte type;

    private Class<? extends Protocol> protocol;

    private static Map<Byte, ProtocolEnum> cache = new HashMap<>();

    static {
        for (ProtocolEnum protocolEnum : values()) {
            cache.put(protocolEnum.type, protocolEnum);
        }
    }

    public static ProtocolEnum byType(byte type) {
        return cache.get(type);
    }
}    

3. 工具类

工具类常为无状态对象,无状态对象都是线程安全对象,建议使用 final 修饰。

工具类中避免出现业务属性, 如果出现业务属性,抽象出领域层

建议示例
Utils作为后缀StringUtils

4. 异常类

建议保持异常链。

建议示例
Exception结尾RuntimeException

5. 接口实现类

众所周知

建议示例
接口名+ ImplUserServiceImpl

6. 设计模式相关类

建议示例
Builder,Factory等当使用到设计模式时,需要使用对应的设计模式作为后缀,如ThreadFactory

7. 处理特定功能的

其主要的目的是代码可重复使用。

建议示例
Handler,Predicate, Validator表示处理器,校验器,断言,这些类工厂还有配套的方法名如handle,predicate,validate

8. 测试类

建议示例
Test结尾UserServiceTest, 表示用来测试UserService类的

9. 领域模型载体

建议示例
DTO/*Request数据传输对象
BO业务对象
VO数据展示对象,用于承载页面数据
DO数据持久化对象

二、方法命名

参考于网络。

1. 布尔判断方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

位置单词意义
Prefixis对象是否符合期待的状态isValid
Prefixcan对象能否执行所期待的动作canRemove
Prefixshould调用方执行某个命令或方法是好还是不好,应不应该,或者说推荐还是不推荐shouldMigrate
Prefixhas对象是否持有所期待的数据和属性hasObservers
Prefixneeds调用方是否需要执行某个命令或方法needsMigrate

2. 检查的方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

单词意义
ensure检查是否为期待的状态,不是则抛出异常或返回error codeensureCapacity
validate检查是否为正确的状态,不是则抛出异常或返回error codevalidateInputs

3. 按需求才执行的方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

位置单词意义
SuffixIfNeeded需要的时候执行,不需要的时候什么都不做drawIfNeeded
Prefixmight同上mightCreate
Prefixtry尝试执行,失败时抛出异常或是返回errorcodetryCreate
SuffixOrDefault尝试执行,失败时返回默认值getOrDefault
SuffixOrElse尝试执行、失败时返回实际参数中指定的值getOrElse
Prefixforce强制尝试执行。error抛出异常或是返回值forceCreate, forceStop

4. 异步相关方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

位置单词意义
Prefixblocking线程阻塞方法blockingGetUser
SuffixInBackground执行在后台的线程doInBackground
SuffixAsync异步方法sendAsync
SuffixSync对应已有异步方法的同步方法sendSync
Prefix or AlonescheduleJob和Task放入队列schedule, scheduleJob
Prefix or Alonepost同上postJob
Prefix or Aloneexecute执行异步方法(注:我一般拿这个做同步方法名)execute, executeTask
Prefix or Alonestart同上start, startJob
Prefix or Alonecancel停止异步方法cancel, cancelJob
Prefix or Alonestop同上stop, stopJob

5. 回调方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

位置单词意义
Prefixon事件发生时执行onCompleted
Prefixbefore事件发生前执行beforeUpdate
Prefixpre同上preUpdate
Prefixwill同上willUpdate
Prefixafter事件发生后执行afterUpdate
Prefixpost同上postUpdate
Prefixdid同上didUpdate
Prefixshould确认事件是否可以发生时执行shouldUpdate

6. 操作对象生命周期的方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

单词意义
initialize初始化。也可作为延迟初始化使用initialize
pause暂停onPause ,pause
stop停止onStop,stop
abandon销毁的替代abandon
destroy同上destroy
dispose同上dispose

7. 与集合操作相关的方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

单词意义
contains是否持有与指定对象相同的对象contains
add添加addJob
append添加appendJob
insert插入到下标ninsertJob
put添加与key对应的元素putJob
remove移除元素removeJob
enqueue添加到队列的最末位enqueueJob
dequeue从队列中头部取出并移除dequeueJob
push添加到栈头pushJob
pop从栈头取出并移除popJob
peek从栈头取出但不移除peekJob
find寻找符合条件的某物findById

8. 数据增删改查相关的方法

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

单词意义
create新创建createAccount
new新创建newAccount
from从既有的某物新建,或是从其他的数据新建fromConfig
to转换toString
update更新既有某物updateAccount
load读取loadAccount
fetch远程读取fetchAccount
delete删除deleteAccount
remove删除removeAccount
save保存saveAccount
store保存storeAccount
commit保存commitChange
apply保存或应用applyChange
clear清除数据或是恢复到初始状态clearAll
reset清除数据或是恢复到初始状态resetAll

9. 成对出现的动词

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

单词意义
get获取set 设置
add 增加remove 删除
create 创建destory 移除
start 启动stop 停止
open 打开close 关闭
read 读取write 写入
load 载入save 保存
create 创建destroy 销毁
begin 开始end 结束
backup 备份restore 恢复
import 导入export 导出
split 分割merge 合并
inject 注入extract 提取
attach 附着detach 脱离
bind 绑定separate 分离
view 查看browse 浏览
edit 编辑modify 修改
select 选取mark 标记
copy 复制paste 粘贴
undo 撤销redo 重做
insert 插入delete 移除
add 加入append 添加
clean 清理clear 清除
index 索引sort 排序
find 查找search 搜索
increase 增加decrease 减少
play 播放pause 暂停
launch 启动run 运行
compile 编译execute 执行
debug 调试trace 跟踪
observe 观察listen 监听
build 构建publish 发布
input 输入output 输出
encode 编码decode 解码
encrypt 加密decrypt 解密
compress 压缩decompress 解压缩
pack 打包unpack 解包
parse 解析emit 生成
connect 连接disconnect 断开
send 发送receive 接收
download 下载upload 上传
refresh 刷新synchronize 同步
update 更新revert 复原
lock 锁定unlock 解锁
check out 签出check in 签入
submit 提交commit 交付
push 推pull 拉
expand 展开collapse 折叠
begin 起始end 结束
start 开始finish 完成
enter 进入exit 退出
abort 放弃quit 离开
obsolete 废弃depreciate 废旧
collect 收集aggregate 聚集

10. 获取必须的参数

getRequiredProperty获取必须的参数,否则报错,该方法一般都要抛出异常
getProperty非必须参数,可以返回null,不报错,调用方自行判断处理逻辑

11. 获取数据并对数据进行某种处理

注:Prefix-前缀,Suffix-后缀,Alone-单独使用

位置单词意义例子
Prefixresolve解决某些问题,比如对文本占位符进行填充,并获取到填充后的值resolvePlaceholders
SuffixPlaceholders占位符相关命名resolvePlaceholders

三、方法编程建议

1. 方法复杂度

凡是逻辑判断语句均为复杂度。当一个方法中出现了大于等于10个复杂度。建议根据

方法实现进行业务抽离。两个建议点(1. 方法单一职责 2. 方法可重复利用 3. 是否能用策略模式或者命令模式)

2.方法长度及宽度

长度: 方法的长度建议控制在80-120行以内。满足一屏可以放下。
宽度: 当方法超过3个及以上入参,建议使用对象封装(对象容易后期扩展,且不会出现眼花缭乱现象)

3.关注方法优化编辑器提示

减少出现黄色警告⚠️, 最好不要出现警告。编辑器的警告都是优化点,需要在编程时候考虑进去。

eg: 性能优化、命名不规范、重复代码

img

4.方法重复代码

贫血模型的标志性问题

重复代码编辑器会提出警告,此种现象,强烈建议不要出现

5. 方法注释

注释是必须要做的(先写注释在做实现),重在设计。

代码是公司财产, 要对自己对公司对后人负责,先写注释再做实现。

四、项目依赖模型

1. 领域设计的认识

领域划分,用另外一个词形容也非常的合适,就是业务模块化。所有能力都进行能力化抽象,形成模块,形成领域。 当遇到新的业务逻辑,底层的数据结构和数据关系肯定也是一样的。那么就可以像堆积木一样,根据这些模块快速的组装成新的业务逻辑。快速的实现业务的迭代和升级。

关于这个问题,需要结合自己的业务系统来进行抽象和设计。

设计核心: 用面向对象的设计思想对业务进行解耦来做到领域划分。

2. 层次划分

基础层(外部调用,db操作)

注意: 基础层只做适配不做业务

  • db操作以dao结尾
  • 外部调用以Client(Http协议)/Instruction(Rpc协议)
    • 改层仅仅做数据适配,不做业务处理。
领域层(偏向领域的业务逻辑)

以Manager

业务层(对领域层的业务编排)

以Service结尾

外观层(可以提供能力,可以提供视图)。

以Resource、Facade结尾

有一个完善的领域层,可以方便快速便捷的对业务进行扩展。与其对立的就是贫血模型。没有领域层只有业务层,业务逻辑都堆积在业务层。典型的面向过程设计。

img

3. 层次依赖模型

maven多模块应用和单模块应用通用。

一定要控制项目的依赖情况。

①service只能出现领域层的依赖, 领域层只能存在dao层和第三方服务层。

②各个层代码不能平行调用(出现平行调用逻辑,要抽象出领域层来封装)。

img

具体代码体现就是

  • 以Service命名的类,里面只能存在Manager
  • 以Manager命名的类,里面只能存在Dao和Client(Http协议)/Instruction(Rpc协议)封装的第三方调用
  • 以Dao命名的类是对数据库的操作
  • 以Client(Http协议)/Instruction(Rpc协议)命名的类,作为适配层与第三方API进行交互封装

五、设计模式六大原则

代码编程时候要向以下这6大原则,进行向其靠拢。

1. 开闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。

代码设计建议

用抽象构建框架,用实现扩展细节因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。

2. 单一职责

不要存在多于一个导致类变更的原因通俗的说,即一个类只负责一项职责。

代码设计建议

在具体方法编写或者类编写时候,类编写时候业务要单一,方法编写时候实现要单一

反例:

UserService 类中提供了获取商品信息的接口

setUserName(String name)方法的时候,对name的值进行了二次处理。

3. 里氏替换原则

所有引用基类的地方必须能透明地使用其子类的对象。

代码设计建议

面向接口编程, 子类能透明替换父类。

4. 依赖倒置原则

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

代码设计建议

要根据接口或者抽象去设计,不要依赖于细节,eg.项目中要换数据库,不用重新写底层的数据库代码. 就是使用了hibernate一样,替换方言就好了,因为hibernate是根据接口设计的,不同数据库有不同的实现,可以直接使用. eg2: 我生病了要去买药,如果A药铺,没有我就用B药铺买. 因为他们都是药铺,都有一样的功能,可以友好的替换

5. 接口隔离原则

客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

代码设计建议

保持最小的责任。

eg: 接口ConfigurableApplicationContext实现了Lifecycle和Closeable接口。他们其中每个里面定义的接口都很少,为什么不定义到一起呢?

首先第一责任清晰单一,第二做到接口隔离。

当某一个方法只用到生命周期的方法,那么方法就可以写成。

public void stop(Lifecycle lifecycle); 调用时候用->public void stop(new ConfigurableApplicationContext());

public void close(Closeable closeable); 调用时候用->public void close(new ConfigurableApplicationContext());

stop里面的实现就只能调用Lifecycle里面的方法,而不能调用ConfigurableApplicationContext里面的方法。从而来达到接口隔离原则

6. 迪米特法则

一个对象应该对其他对象保持最少的了解。

代码设计建议

减少类与类之间的关系,接口隔离也可以做到。

六、版本迭代

master分支版本后缀 大版本号 . {大版本号}. 大版本号.{0进位}.${迭代版本号}.RELEASE

test分支版本号 大版本号 . {大版本号}. 大版本号.{0进位}.${迭代版本号}.SNAPSHOP

迭代版本可追踪,避免出现jar包覆盖无法追踪

迭代版本升级,必须升级迭代版本号。避免出现jar包覆盖无法追踪

1. 大版本定义

APP1.0 APP2.0 APP3.0

2. 迭代版本号

APP1.0.1 APP1.0版本的第一个迭代

APP1.1.0 APP1.0版本的第十个迭代

APP2.0.2 APP2.0版本的第二个迭代

APP2.1.0 APP2.0版本的第十个迭代

七、代码格式化

统一格式化模板,解决多人共同开发场景,代码格式化导致的git提交冲突问题

最后求关注,求订阅,谢谢你的阅读!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西魏陶渊明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值