行为接口重构的核心是厘清职责边界而非单纯增加接口;通过提取统一契约、构造器注入、数据与行为内聚、枚举驱动策略,实现高内聚低耦合。

用行为接口重构系统,核心不是加接口,而是把“谁该做什么”重新划清楚。接口本身不降低耦合,真正起作用的是接口背后职责的收敛与隔离。
先识别行为边界:从if-else和类型判断中挖出隐含策略
看到类似下面的代码,就说明行为逻辑已经混杂:
- if (type.equals("email")) sendEmail(...); else if (type.equals("sms")) sendSms(...);
- switch (paymentMethod) { case "alipay": ... case "wechat": ... }
- order.getStatus().equals("PAID") ? applyDiscount() : logWarning();
这些不是业务复杂,是行为没被抽象。应提取统一的行为契约,比如:
public interface NotificationSender {
void send(String target, String content);
boolean supports(String channel); // 显式声明能力边界
}每个实现类只专注一种通道——EmailSender、SmsSender、PushSender,不再互相知道对方存在。
立即学习“Java免费学习笔记(深入)”;
用构造器注入代替new + 接口依赖代替具体实现
重构后,业务类不再创建行为实现,只声明所需能力:
public class OrderService {
private final PaymentProcessor paymentProcessor;
private final NotificationSender notificationSender;
<pre class="brush:php;toolbar:false;">public OrderService(PaymentProcessor processor, NotificationSender sender) {
this.paymentProcessor = processor;
this.notificationSender = sender;
}
public void completeOrder(Order order) {
paymentProcessor.process(order);
notificationSender.send(order.getContact(), "订单已支付");
}}
关键点:
- 所有依赖通过构造器传入,不可变、可测、无隐藏依赖
- 依赖类型是接口,不是AlipayProcessorImpl这类具体类
- 测试时直接传入new MockPaymentProcessor(),无需Spring容器
把状态与行为绑定到同一语义主体,避免DTO+Helper模式
别再写UserDto + UserHelper。高内聚要求数据和它该做的事在一起:
public class User {
private String email;
private LocalDateTime lastLogin;
<pre class="brush:php;toolbar:false;">public boolean isValidEmail() {
return email != null && email.contains("@");
}
public boolean isInactiveForDays(int days) {
return Duration.between(lastLogin, LocalDateTime.now()).toDays() > days;
}}
这样调用方写user.isValidEmail(),比UserHelper.isValid(user.getEmail())更自然、更内聚。若逻辑跨领域(如“用户是否可下单”需查库存+信用分),就新建OrderEligibilityChecker类,而不是塞进User或Order里。
用枚举驱动行为选择,消除硬编码分支
当行为类型固定且有限(如通知渠道、支付方式、审批状态),用枚举聚合行为比if-else更安全、更易维护:
public enum NotificationChannel {
EMAIL { @Override public void send(String to, String msg) { /* 邮件逻辑 */ } },
SMS { @Override public void send(String to, String msg) { /* 短信逻辑 */ } };
<pre class="brush:php;toolbar:false;">public abstract void send(String to, String msg);}
使用时直接channel.send(...),新增渠道只需加枚举项,不改调用方代码。这既是策略模式的轻量实现,也天然支持编译期检查,避免字符串拼写错误。


















