RuoYi代码规范:阿里巴巴Java开发规约落地实践
引言:为什么需要代码规范?
在企业级Java开发中,代码规范不仅是编码风格的统一,更是团队协作效率、代码质量和系统可维护性的重要保障。阿里巴巴Java开发规约作为国内Java开发的事实标准,为开发者提供了全面的编码指导。RuoYi作为一款优秀的开源权限管理系统,其代码规范实践值得深入学习和借鉴。
一、命名规范:见名知意的艺术
1.1 包命名规范
RuoYi严格遵循阿里巴巴规约的包命名要求:
// 正确的包命名示例
package com.ruoyi.common.annotation;
package com.ruoyi.framework.config;
package com.ruoyi.system.service;
包名全部小写,采用反域名命名规则,层级清晰,功能模块明确。
1.2 类与接口命名
RuoYi中的类命名采用大驼峰式(UpperCamelCase),接口命名同样遵循此规则:
// 类命名示例
public class SysUserController extends BaseController
public class StringUtils extends org.apache.commons.lang3.StringUtils
// 接口命名示例
public interface ISysUserService
public interface IGenTableService
1.3 方法命名规范
方法命名采用小驼峰式(lowerCamelCase),动词开头,表意明确:
// 方法命名示例
public AjaxResult selectUserById(Long userId)
public boolean checkLoginNameUnique(SysUser user)
public static String toUnderScoreCase(String str)
1.4 常量与变量命名
常量全大写,单词间用下划线分隔;变量小驼峰式:
// 常量命名
public static final String CODE_TAG = "code";
private static final String NULLSTR = "";
// 变量命名
private ISysUserService userService;
private String prefix = "system/user";
二、代码格式:统一的视觉规范
2.1 缩进与换行
RuoYi采用4个空格缩进,方法参数换行保持对齐:
public AjaxResult success(String msg, Object data)
{
return new AjaxResult(Type.SUCCESS, msg, data);
}
// 多参数方法换行示例
public static final List<String> str2List(String str, String sep,
boolean filterBlank, boolean trim)
2.2 大括号风格
采用Kernighan和Ritchie风格(K&R风格),左大括号不换行:
public class AjaxResult extends HashMap<String, Object>
{
private static final long serialVersionUID = 1L;
public AjaxResult()
{
}
}
2.3 空行规范
RuoYi代码中合理使用空行增强可读性:
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
/** 空字符串 */
private static final String NULLSTR = "";
/** 下划线 */
private static final char SEPARATOR = '_';
// 方法间空一行
public static boolean isEmpty(String str)
{
return isNull(str) || NULLSTR.equals(str.trim());
}
public static boolean isNotEmpty(String str)
{
return !isEmpty(str);
}
}
三、OOP规约:面向对象的最佳实践
3.1 类的单一职责原则
RuoYi中的每个类都职责明确,如:
3.2 接口隔离原则
RuoYi通过细粒度接口设计实现接口隔离:
// 系统服务接口定义
public interface ISysUserService
{
SysUser selectUserById(Long userId);
List<SysUser> selectUserList(SysUser user);
int insertUser(SysUser user);
int updateUser(SysUser user);
int deleteUserByIds(String ids);
boolean checkLoginNameUnique(SysUser user);
}
// 代码生成服务接口
public interface IGenTableService
{
List<GenTable> selectGenTableList(GenTable genTable);
GenTable selectGenTableById(Long tableId);
void validateEdit(GenTable genTable);
void updateGenTable(GenTable genTable);
}
3.3 使用枚举替代常量
RuoYi大量使用枚举类型,提高代码可读性和类型安全:
public enum Type
{
/** 成功 */
SUCCESS(0),
/** 警告 */
WARN(301),
/** 错误 */
ERROR(500);
private final int value;
Type(int value)
{
this.value = value;
}
public int value()
{
return this.value;
}
}
四、异常处理:优雅的错误管理
4.1 自定义业务异常
RuoYi定义了统一的业务异常体系:
public final class ServiceException extends RuntimeException
{
private static final long serialVersionUID = 1L;
private String message;
private String detailMessage;
public ServiceException(String message)
{
this.message = message;
}
// 链式调用支持
public ServiceException setDetailMessage(String detailMessage)
{
this.detailMessage = detailMessage;
return this;
}
}
4.2 异常使用规范
在业务代码中统一使用异常处理:
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
{
if (!userService.checkLoginNameUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
// 业务逻辑...
}
五、注释规范:代码即文档
5.1 类与方法注释
RuoYi采用标准的JavaDoc注释规范:
/**
* 字符串工具类
*
* @author ruoyi
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
/**
* * 判断一个Collection是否为空, 包含List,Set,Queue
*
* @param coll 要判断的Collection
* @return true:为空 false:非空
*/
public static boolean isEmpty(Collection<?> coll)
{
return isNull(coll) || coll.isEmpty();
}
}
5.2 代码逻辑注释
对于复杂算法和业务逻辑添加详细注释:
/**
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str)
{
if (str == null)
{
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
// 复杂的转换逻辑注释...
}
return sb.toString();
}
六、安全规约:防御式编程实践
6.1 参数校验
RuoYi在各个环节都进行严格的参数校验:
public AjaxResult addSave(@Validated SysUser user)
{
// 数据权限校验
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
// 业务规则校验
if (!userService.checkLoginNameUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在");
}
// 数据完整性校验
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{
return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在");
}
}
6.2 SQL注入防护
使用MyBatis预编译语句防止SQL注入:
<!-- MyBMapper XML配置 -->
<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
select u.user_id, u.dept_id, u.login_name, u.user_name, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
where u.del_flag = '0'
<if test="userName != null and userName != ''">
AND u.user_name like concat('%', #{userName}, '%')
</if>
<if test="status != null and status != ''">
AND u.status = #{status}
</if>
<if test="phonenumber != null and phonenumber != ''">
AND u.phonenumber like concat('%', #{phonenumber}, '%')
</if>
</select>
七、工程结构:模块化设计理念
RuoYi采用清晰的模块化结构,符合阿里巴巴规约的工程组织要求:
7.1 分层架构规范
RuoYi严格遵循MVC分层架构:
| 层级 | 职责 | 示例 |
|---|---|---|
| Controller | 请求处理、参数校验 | SysUserController |
| Service | 业务逻辑、事务管理 | SysUserServiceImpl |
| Mapper | 数据持久化操作 | SysUserMapper |
| Domain | 数据模型、实体类 | SysUser |
7.2 依赖管理规范
通过Maven进行规范的依赖管理:
<!-- 父POM统一管理版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
</parent>
<!-- 子模块依赖声明 -->
<dependencies>
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
</dependencies>
八、日志规约:可追溯的操作记录
8.1 操作日志注解
RuoYi使用自定义注解记录操作日志:
@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping("/add")
@ResponseBody
public AjaxResult addSave(@Validated SysUser user)
{
// 业务逻辑
return toAjax(userService.insertUser(user));
}
8.2 日志级别规范
根据不同场景使用合适的日志级别:
// 错误日志记录
logger.error("用户登录失败,用户名:{}", username, e);
// 警告日志记录
logger.warn("用户密码错误次数过多,用户名:{}", username);
// 信息日志记录
logger.info("用户登录成功,用户名:{}", username);
// 调试日志记录
logger.debug("查询用户参数:{}", user);
九、测试规约:质量保障体系
9.1 单元测试规范
RuoYi虽然没有提供完整的测试用例,但遵循测试规范:
// 单元测试示例结构
@SpringBootTest
public class SysUserServiceTest
{
@Autowired
private ISysUserService userService;
@Test
public void testSelectUserById()
{
SysUser user = userService.selectUserById(1L);
Assert.assertNotNull(user);
Assert.assertEquals("admin", user.getLoginName());
}
@Test
public void testCheckLoginNameUnique()
{
SysUser user = new SysUser();
user.setLoginName("admin");
boolean result = userService.checkLoginNameUnique(user);
Assert.assertFalse(result);
}
}
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



