反模式 1:魔法数字/字符串(Magic Numbers/Strings)
▐ 问题场景
java
// 订单状态校验
if (order.getStatus() == 3) { // 3代表已发货?
sendNotification();
}
// 折扣计算
double discount = price * 0.15; // 0.15是什么?
危害:
- 可读性差,维护者需要猜测数字含义
- 修改时需要全局搜索,容易遗漏
- 业务规则分散,违反单一真相源原则
▐ 重构方案
步骤 1:常量替换
java
// 创建常量类
public class OrderConstants {
public static final int STATUS_SHIPPED = 3;
public static final double VIP_DISCOUNT_RATE = 0.15;
}
// 使用常量
if (order.getStatus() == OrderConstants.STATUS_SHIPPED) {
sendNotification();
}
double discount = price * OrderConstants.VIP_DISCOUNT_RATE;
步骤 2:进阶枚举化(适合有逻辑关联的状态)
java
public enum OrderStatus {
CREATED(1), PAID(2), SHIPPED(3), COMPLETED(4);
private final int code;
OrderStatus(int code) {
this.code = code;
}
public static OrderStatus fromCode(int code) {
return Arrays.stream(values())
.filter(status -> status.code == code)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
// 使用枚举
if (order.getStatus() == OrderStatus.SHIPPED) {
sendNotification();
}
步骤 3:配置中心化(适合频繁变更的参数)
properties
# application.properties
discount.vip.rate=0.15
java
@Value("${discount.vip.rate}")
private double vipDiscountRate;
▐ 检测工具
- SonarQube 规则:
squid:S109
(魔法数字检测) - IDEA 插件:
MagicConstant
(自动提示替换)
反模式 2:神对象(God Object)
▐ 问题场景
java
public class OrderProcessor {
// 处理订单逻辑
public void process(Order order) { /* 200行逻辑 */ }
// 数据库操作
public void saveToDB(Order order) { /* 直接JDBC操作 */ }
// 日志记录
private void log(String message) { /* 自定义日志格式 */ }
// 发送短信
public void sendSMS(String phone) { /* 调用第三方API */ }
}
危害:
- 单文件代码量超过1000行
- 牵一发而动全身,修改风险高
- 无法单独测试某个功能模块
▐ 重构方案
步骤 1:职责拆分
java
// 领域对象
public class Order {
// 订单核心属性与方法
}
// 持久化层
@Repository
public class OrderRepository {
public void save(Order order) { /* JPA实现 */ }
}
// 服务层
@Service
public class OrderService {
private final OrderRepository repository;
private final NotificationService notificationService;
public void processOrder(Order order) {
// 核心业务逻辑
repository.save(order);
notificationService.sendSMS(order.getUser());
}
}
// 基础设施层
@Service
public class NotificationService {
public void sendSMS(String phone) { /* 调用第三方API */ }
}
步骤 2:依赖注入
java
// 使用Spring的构造函数注入
@Service
public class OrderService {
private final OrderRepository repository;
private final NotificationService notificationService;
public OrderService(OrderRepository repository,
NotificationService notificationService) {
this.repository = repository;
this.notificationService = notificationService;
}
}
步骤 3:领域驱动设计
java
// 订单聚合根
public class Order {
public void ship() {
validateShippingConditions();
this.status = OrderStatus.SHIPPED;
}
}
// 领域服务
public class ShippingService {
public void scheduleShipping(Order order) {
order.ship();
// 调度物流系统
}
}
▐ 重构指标验证
- 类行数:从 1000+ 行 → 每个类 < 300 行
- 单元测试覆盖率:从 10% → 85%+
- 依赖关系:从 20+ 个依赖 → 每个类 < 5 个依赖
反模式 3:霰弹式修改(Shotgun Surgery)
▐ 问题场景
当需要修改用户身份验证规则时,需要改动:
1. LoginController.java
2. UserService.java
3. AuthFilter.java
4. SecurityConfig.java
5. audit.log
根本原因:
- 认证逻辑分散在多个层
- 没有统一的认证抽象
▐ 重构方案
步骤 1:建立防腐层
java
public interface AuthenticationGateway {
User authenticate(String username, String password);
}
@Component
public class DefaultAuthGateway implements AuthenticationGateway {
// 集中实现所有认证逻辑
}
步骤 2:统一调用点
java
// 所有认证入口调用网关
@Controller
public class LoginController {
private final AuthenticationGateway authGateway;
public void login(String user, String pwd) {
User user = authGateway.authenticate(user, pwd);
// ...
}
}
// 过滤器
public class AuthFilter {
private final AuthenticationGateway authGateway;
public void doFilter() {
User user = authGateway.authenticate(...);
// ...
}
}
步骤 3:策略模式扩展
java
public class OAuthAuthentication implements AuthenticationGateway {
// 实现OAuth认证
}
// 通过配置切换实现
@ConditionalOnProperty(name = "auth.mode", havingValue = "oauth")
@Component
public class OAuthAuthConfig {
@Bean
public AuthenticationGateway authGateway() {
return new OAuthAuthentication();
}
}
▐ 重构效果验证
- 修改点:从 5 个文件 → 1 个接口+1 个实现类
- 测试用例:只需修改网关的单元测试
- 扩展性:新增认证方式无需修改业务代码
反模式改进工作台
反模式 | 重构技术 | 风险指数 | 预计工时 | 关键检查点 |
---|---|---|---|---|
魔法数字 | 常量提取+配置中心 | ★☆☆☆☆ | 2h | 确保全量替换 |
神对象 | DDD分层+依赖倒置 | ★★★☆☆ | 8h | 接口隔离测试 |
霰弹式修改 | 防腐层+策略模式 | ★★☆☆☆ | 4h | 回归测试覆盖所有调用点 |
重构验证 Checklist
-
功能等价性:
- 新旧版本输出结果完全一致
- 所有边界条件测试通过
-
质量提升:
- 圈复杂度降低30%以上
- 单元测试覆盖率 ≥ 80%
-
可维护性:
- 新增功能只需修改1个文件
- 关键类有清晰的接口文档