Java代码质量案例
代码可读性案例
1 命名规范 ❌ 不良案例
public class Test {
private String n; // 不清楚含义
private int d; // 日期?数据?
public void doIt() { // 做了什么不清楚
// 处理逻辑
}
public List<String> getData() {
List<String> l = new ArrayList<>();
// 某个复杂的查询逻辑
return l;
}
}
✅ 改进案例

public class UserProfile {
private String userName;
private LocalDate registrationDate;
public void updateProfile() {
// 清晰的业务意图
}
public List<String> fetchUserPermissions() {
List<String> permissions = new ArrayList<>();
// 清晰的查询逻辑
return permissions;
}
}
2 方法长度控制 ❌ 过长的上帝方法
public void processOrder(Order order) {
// 验证订单
if (order.getTotal() > 0) { // 20行代码
// ...
}
// 计算折扣 (30行代码)
double discount = order.getTotal() * 0.1;
// ... 很多计算
// 通知客户 (25行代码)
// 发送邮件、短信等
// 更新库存 (30行代码)
// 各种库存操作
// 生成报表 (40行代码)
// 生成各种统计
}
✅ 改进案例 - 单一职责方法
public void processOrder(Order order) {
validateOrder(order);
double finalPrice = calculatePrice(order);
updateInventory(order);
notifyCustomer(order, finalPrice);
}
private void validateOrder(Order order) {
// 只做验证
}
private double calculatePrice(Order order) {
// 只做计算
}
private void updateInventory(Order order) {
// 只做库存
}
private void notifyCustomer(Order order, double price) {
// 只做通知
}
错误处理案例
1 异常处理 ❌ 盲目catch
try {
// 业务逻辑
connection.execute(sql);
fileProcessor.read(file);
apiCall.send(data);
} catch (Exception e) {
// 什么异常都捕获了
logger.error("some error");
// 没给出具体问题
}
✅ 精细异常处理
try {
connection.execute(sql);
fileProcessor.read(file);
apiCall.send(data);
} catch (SQLException e) {
logger.error("数据库操作失败: {}", sql, e);
throw new DataAccessException("数据库操作异常", e);
} catch (IOException e) {
logger.error("文件读取失败: {}", file.getName(), e);
throw new BusinessException("文件处理失败", e);
} catch (ApiException e) {
logger.error("第三方接口调用失败, code={}", e.getCode(), e);
throw new BusinessException("外部服务异常", e);
}
2 空值处理 ❌ 忽略空值
public String getAddress(User user) {
Address address = user.getAddress();
return address.getStreet() + ", " + address.getCity();
// NPE风险,如果user或address为null
}
✅ 防御性编程
public String getAddress(User user) {
if (user == null) {
return "未知用户";
}
Address address = user.getAddress();
if (address == null) {
return "地址未填写";
}
return String.format("%s, %s",
address.getStreet(),
address.getCity());
}
// 或者使用 Optional
public Optional<String> getAddress(Optional<User> user) {
return user.map(User::getAddress)
.map(address -> address.getStreet() + ", " + address.getCity());
}
性能优化案例
1 循环处理 ❌ 低效SQL
// ❌ N+1查询问题
List<Order> orders = orderDao.findAll();
for (Order order : orders) {
List<OrderItem> items = orderItemDao.findByOrderId(order.getId()); // 每次循环都查库
order.setItems(items);
}
✅ 批量查询优化
// ✅ 批量查询
List<Order> orders = orderDao.findAll();
List<Long> orderIds = orders.stream()
.map(Order::getId)
.collect(Collectors.toList());
Map<Long, List<OrderItem>> itemsMap = orderItemDao
.findByOrderIds(orderIds) // 一次查询全部
.stream()
.collect(Collectors.groupingBy(OrderItem::getOrderId));
orders.forEach(order -> order.setItems(itemsMap.getOrDefault(order.getId(), new ArrayList<>())));
2 字符串拼接 ❌ 循环拼接
public String buildReport(List<String> lines) {
String result = "";
for (String line : lines) {
result = result + line + "\n"; // 每次创建新对象
}
return result;
}
✅ 使用StringBuilder
public String buildReport(List<String> lines) {
StringBuilder sb = new StringBuilder();
for (String line : lines) {
sb.append(line).append('\n');
}
return sb.toString();
}
并发安全案例
1 集合类型选择 ❌ 线程不安全
public class OrderService {
private HashMap<String, Order> orderCache = new HashMap<>(); // 线程不安全
public void addOrder(String key, Order order) {
orderCache.put(key, order); // 并发问题
}
}
✅ 正确使用并发集合
public class OrderService {
private ConcurrentHashMap<String, Order> orderCache = new ConcurrentHashMap<>();
public void addOrder(String key, Order order) {
orderCache.put(key, order); // 线程安全
}
public Order getOrderIfAbsent(String key, String orderId) {
return orderCache.computeIfAbsent(key, k -> fetchOrder(orderId)); // 避免重复查询
}
}
2 原子操作 ❌ 检查然后处理(非原子)
// ❌ 非原子操作 -竞态条件
public class Counter {
private int count = 0;
public void increment() {
if (count < 100) { // 先检查
count++; // 再修改(中间可能被其他线程中断)
}
}
}
✅ 使用原子类或同步
// ✅ 原子类
public class Counter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() {
count.getAndIncrement();
}
public boolean tryIncrement() {
while (true) {
int current = count.get();
if (current >= 100) {
return false;
}
if (count.compareAndSet(current, current + 1)) { // 原子操作
return true;
}
}
}
}
// ✅ 或使用 synchronized
public class Counter {
private int count = 0;
public synchronized void increment() {
if (count < 100) {
count++;
}
}
}
设计模式案例
1 工厂模式 ❌ 大量if-else
public class PaymentProcessor {
public void processPayment(String type, PaymentRequest request) {
if ("alipay".equals(type)) {
// 支付宝逻辑 50行
} else if ("wechat".equals(type)) {
// 微信逻辑 50行
} else if ("card".equals(type)) {
// 银行卡逻辑 50行
} else {
throw new IllegalArgumentException("不支持的支付方式: " + type);
}
}
}
✅ 策略模式+工厂
// 支付策略接口
public interface PaymentStrategy {
void pay(PaymentRequest request);
}
// 支付宝实现
@Component
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(PaymentRequest request) {
// 支付宝专用逻辑
}
}
// 微信实现
@Component
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(PaymentRequest request) {
// 微信专用逻辑
}
}
// 工厂类
@Component
public class PaymentStrategyFactory {
private final Map<String, PaymentStrategy> strategyMap;
@Autowired
public PaymentStrategyFactory(List<PaymentStrategy> strategies) {
strategyMap = strategies.stream()
.collect(Collectors.toMap(
s -> s.getClass().getSimpleName().replace("Strategy", "").toLowerCase(),
Function.identity()
));
}
public PaymentStrategy getStrategy(String type) {
PaymentStrategy strategy = strategyMap.get(type.toLowerCase());
if (strategy == null) {
throw new IllegalArgumentException("不支持的支付方式: " + type);
}
return strategy;
}
}
代码测试案例
1 单元测试 ❌ 缺少测试
public class UserService {
public boolean validateUser(String username, String password) {
// 复杂验证逻辑
if (username.length() < 3) return false;
if (password.length() < 8) return false;
// ... 更多验证
return true;
}
}
✅ 边界测试
class UserServiceTest {
private UserService userService = new UserService();
@Test
@DisplayName("用户名校验")
public void testValidateUsername() {
// 最小长度
assertFalse(userService.validateUser("ab", "password123"));
// 恰好长度
assertTrue(userService.validateUser("abc", "password123"));
// 含特殊字符
assertFalse(userService.validateUser("abc@123", "password123"));
}
@Test
@DisplayName("密码强度校验")
public void testValidatePassword() {
// 短密码
assertFalse(userService.validateUser("abc", "short"));
// 正好8位
assertTrue(userService.validateUser("abc", "pass1234"));
// 空密码
assertFalse(userService.validateUser("abc", ""));
}
@Test
@DisplayName("空值处理")
public void testNullValidation() {
assertThrows(IllegalArgumentException.class,
() -> userService.validateUser(null, "password"));
}
}
代码审查清单
以下是在代码审查时的检查重点:
/**
* 代码质量检查清单
*/
public class CodeQualityChecklist {
// 1. 可读性
// □ 命名清晰有意义
// □ 方法简短单一职责
// □ 复杂逻辑有注释
// 2. 健壮性
// □ 处理了空值和边界情况
// □ 有异常处理和错误信息
// □ 参数进行了验证
// 3. 性能
// □ 避免N+1查询
// □ 使用合适的数据结构
// □ 避免不必要的对象创建
// 4. 并发
// □ 使用线程安全集合
// □ 原子操作
// □ 同步策略明确
// 5. 可测试
// □ 方法易于测试
// □ 依赖可注入
// □ 有单元测试
// 6. 设计
// □ 遵循SOLID原则
// □ 使用适当的设计模式
// □ 避免重复代码
}
这些案例展示了从简单到复杂的代码质量提升方法,在实际开发中,应该根据项目需求选择适当的改进方式,并与团队成员达成一致的代码规范。代码质量是一个持续改进的过程,而不是一次性完成的任务。