Java代码质量案例

wen java案例 3

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;
    }
}

✅ 改进案例

Java代码质量案例

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原则
    //  □ 使用适当的设计模式
    //  □ 避免重复代码
}

这些案例展示了从简单到复杂的代码质量提升方法,在实际开发中,应该根据项目需求选择适当的改进方式,并与团队成员达成一致的代码规范。代码质量是一个持续改进的过程,而不是一次性完成的任务。

抱歉,评论功能暂时关闭!