1. 策略模式初探:为什么我们需要它?
作为一名在Java领域摸爬滚打多年的开发者,我见过太多因为if-else泛滥而难以维护的代码库。记得刚入行时接手过一个电商项目,运费计算模块的代码让我至今难忘——长达200多行的if-else嵌套,每次新增客户类型都要小心翼翼地在迷宫般的条件判断中寻找插入点。这正是策略模式要解决的痛点。
策略模式的核心思想其实很简单:将算法封装成独立的类,使它们可以互相替换。这种模式让算法的变化独立于使用算法的客户代码。想象你有一把瑞士军刀,策略模式就是让你可以随时更换刀头上的工具,而不需要换整把刀。
提示:策略模式特别适合处理那些在运行时需要根据不同条件选择不同算法或业务规则的场景。比如支付方式选择、促销策略计算、日志级别处理等。
在实际项目中,策略模式带来的好处显而易见:
- 代码更干净:消除了复杂的条件语句
- 扩展更容易:新增策略只需添加新类,无需修改现有代码
- 测试更简单:每个策略可以独立测试
- 维护更轻松:修改一个策略不会影响其他策略
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与基础概念
2.1 开发环境配置
虽然策略模式是语言无关的设计思想,但为了这篇教程的实操性,我们以Java环境为例。你只需要:
- JDK 8或更高版本(推荐JDK 17,它提供了更好的性能和新特性)
- 一个趁手的IDE:IntelliJ IDEA社区版就足够强大
- (可选)Maven或Gradle构建工具
验证环境是否就绪:
bash复制java -version
# 应该看到类似:openjdk version "17.0.2"...
2.2 策略模式的三大角色
理解策略模式,首先要掌握它的三个核心组成部分:
- 策略接口(Strategy Interface):定义算法的公共接口,所有具体策略都必须实现它
- 具体策略(Concrete Strategies):实现策略接口的具体算法类
- 上下文(Context):持有一个策略对象的引用,通过它来调用具体策略
这种结构的美妙之处在于:上下文类不需要知道具体策略的内部实现,它只通过策略接口与策略交互。这完美体现了面向对象的"针对接口编程,而非实现编程"原则。
3. 从零实现策略模式
3.1 基础实现:运费计算案例
让我们用完整的代码示例来演示策略模式的实际应用。假设我们要为电商系统实现不同的运费计算策略。
首先定义策略接口:
java复制public interface ShippingStrategy {
double calculateShipping(double weight, double distance);
}
然后实现三种具体策略:
java复制// 标准运费策略
public class StandardShipping implements ShippingStrategy {
@Override
public double calculateShipping(double weight, double distance) {
return weight * 1.5 + distance * 0.3;
}
}
// 特快运费策略
public class ExpressShipping implements ShippingStrategy {
@Override
public double calculateShipping(double weight, double distance) {
return weight * 2.5 + distance * 0.5 + 10; // 基础加急费10元
}
}
// 会员免邮策略
public class FreeShipping implements ShippingStrategy {
@Override
public double calculateShipping(double weight, double distance) {
return 0; // 会员免邮
}
}
接着创建上下文类:
java复制public class ShippingContext {
private ShippingStrategy strategy;
public void setStrategy(ShippingStrategy strategy) {
this.strategy = strategy;
}
public double executeCalculation(double weight, double distance) {
if (strategy == null) {
throw new IllegalStateException("Shipping strategy not set");
}
return strategy.calculateShipping(weight, distance);
}
}
最后是使用示例:
java复制public class Main {
public static void main(String[] args) {
ShippingContext context = new ShippingContext();
// 使用标准运费
context.setStrategy(new StandardShipping());
System.out.println("标准运费: " + context.executeCalculation(5, 100));
// 切换为特快运费
context.setStrategy(new ExpressShipping());
System.out.println("特快运费: " + context.executeCalculation(5, 100));
// 会员免邮
context.setStrategy(new FreeShipping());
System.out.println("会员运费: " + context.executeCalculation(5, 100));
}
}
3.2 代码优化与最佳实践
上面的基础实现虽然展示了策略模式的核心思想,但在实际项目中我们还可以做更多优化:
- 使用枚举管理策略类型:
java复制public enum ShippingType {
STANDARD(new StandardShipping()),
EXPRESS(new ExpressShipping()),
FREE(new FreeShipping());
private final ShippingStrategy strategy;
ShippingType(ShippingStrategy strategy) {
this.strategy = strategy;
}
public ShippingStrategy getStrategy() {
return strategy;
}
}
- 结合工厂模式:
java复制public class ShippingStrategyFactory {
public static ShippingStrategy getStrategy(ShippingType type) {
return type.getStrategy();
}
}
- 使用Lambda表达式简化(Java 8+):
java复制// 可以这样定义策略
ShippingStrategy economy = (weight, distance) -> weight * 1.0 + distance * 0.2;
4. 策略模式的高级应用
4.1 与Spring框架集成
在企业级应用中,我们通常会将策略模式与Spring框架结合使用。以下是典型的集成方式:
java复制// 定义策略接口
public interface PaymentStrategy {
void pay(BigDecimal amount);
}
// 实现具体策略
@Component("creditCardPayment")
public class CreditCardPayment implements PaymentStrategy {
@Override
public void pay(BigDecimal amount) {
// 信用卡支付逻辑
}
}
@Component("paypalPayment")
public class PayPalPayment implements PaymentStrategy {
@Override
public void pay(BigDecimal amount) {
// PayPal支付逻辑
}
}
// 使用策略的服务
@Service
public class PaymentService {
private final Map<String, PaymentStrategy> strategies;
@Autowired
public PaymentService(Map<String, PaymentStrategy> strategies) {
this.strategies = strategies;
}
public void processPayment(String paymentType, BigDecimal amount) {
PaymentStrategy strategy = strategies.get(paymentType);
if (strategy == null) {
throw new IllegalArgumentException("未知支付类型: " + paymentType);
}
strategy.pay(amount);
}
}
这种实现方式的优势在于:
- Spring自动管理策略实例的生命周期
- 通过依赖注入获取所有策略实现
- 新增策略只需添加新的@Component类,无需修改现有代码
4.2 策略模式与函数式编程
Java 8引入的Lambda表达式和函数式接口让策略模式的实现更加简洁:
java复制// 定义函数式接口
@FunctionalInterface
public interface DiscountStrategy {
BigDecimal applyDiscount(BigDecimal originalPrice);
}
// 创建策略集合
Map<String, DiscountStrategy> strategies = new HashMap<>();
strategies.put("VIP", price -> price.multiply(new BigDecimal("0.8"))); // 8折
strategies.put("NEW_USER", price -> price.subtract(new BigDecimal("50"))); // 减50
strategies.put("PROMO", price -> price.compareTo(new BigDecimal("200")) > 0 ?
price.subtract(new BigDecimal("30")) : price); // 满200减30
// 使用策略
public BigDecimal calculatePrice(String userType, BigDecimal originalPrice) {
return strategies.getOrDefault(userType, p -> p).applyDiscount(originalPrice);
}
5. 实战经验与避坑指南
5.1 策略模式的常见误用
在实践中,我见过几种策略模式的典型误用:
-
策略类过度膨胀:每个策略类应该只关注一个具体的算法实现。如果发现策略类变得很大,可能需要进一步分解。
-
上下文类过于复杂:上下文类应该只负责维护策略引用和委托调用。如果发现上下文类包含太多逻辑,可能需要重构。
-
策略之间共享状态:策略类应该是无状态的。如果需要共享状态,应该通过上下文类来管理。
5.2 性能考量
虽然策略模式很灵活,但在性能敏感的场景需要考虑:
-
对象创建开销:频繁创建策略对象可能影响性能。可以考虑使用对象池或缓存策略实例。
-
策略切换成本:在需要极高性能的场景,策略接口的方法调用可能比直接方法调用稍慢(虽然现代JVM优化得很好)。
-
内存占用:大量策略类可能增加内存使用。可以使用轻量级策略(如Lambda表达式)来减少开销。
5.3 测试策略
策略模式的一个巨大优势是便于测试。测试策略时:
- 单元测试每个策略:由于每个策略是独立的,可以单独测试。
java复制@Test
public void testStandardShipping() {
ShippingStrategy strategy = new StandardShipping();
assertEquals(15.0, strategy.calculateShipping(10, 0), 0.001);
}
- 测试上下文类:主要验证策略切换和委托是否正确。
java复制@Test
public void testContextStrategySwitching() {
ShippingContext context = new ShippingContext();
context.setStrategy(new StandardShipping());
// 验证结果...
context.setStrategy(new ExpressShipping());
// 验证结果...
}
- 集成测试:验证整个策略系统协同工作是否正常。
6. 策略模式与其他设计模式的关系
6.1 策略模式 vs 状态模式
新手常常混淆策略模式和状态模式,因为它们结构相似。关键区别在于:
- 策略模式:客户端主动选择策略,策略之间通常互不知晓
- 状态模式:状态转换由状态对象自身控制,状态之间知道彼此的存在
举例来说,电商运费计算是策略模式,而订单状态流转(待付款→已付款→已发货)更适合用状态模式。
6.2 策略模式与工厂模式组合
在实际项目中,策略模式常与工厂模式结合使用:
java复制public class StrategyFactory {
public static ShippingStrategy createStrategy(String type) {
switch (type) {
case "STANDARD": return new StandardShipping();
case "EXPRESS": return new ExpressShipping();
case "FREE": return new FreeShipping();
default: throw new IllegalArgumentException("未知策略类型");
}
}
}
这种组合隐藏了策略的创建细节,使客户端代码更简洁。
6.3 策略模式与模板方法模式
模板方法模式在父类中定义算法骨架,而将某些步骤延迟到子类实现。相比之下:
- 策略模式:通过组合委托整个算法
- 模板方法:通过继承定制算法部分步骤
策略模式更灵活(运行时切换),而模板方法模式更严格(编译时确定结构)。
7. 实际项目中的应用案例
7.1 电商促销系统
在一个大型电商平台中,我们使用策略模式实现了复杂的促销系统:
java复制public interface PromotionStrategy {
Order applyPromotion(Order order);
}
// 满减策略
public class FullReductionPromotion implements PromotionStrategy {
@Override
public Order applyPromotion(Order order) {
if (order.getTotal().compareTo(new BigDecimal("300")) >= 0) {
order.setDiscount(order.getDiscount().add(new BigDecimal("30")));
}
return order;
}
}
// 折扣策略
public class DiscountPromotion implements PromotionStrategy {
@Override
public Order applyPromotion(Order order) {
order.setTotal(order.getTotal().multiply(new BigDecimal("0.9")));
return order;
}
}
// 赠品策略
public class GiftPromotion implements PromotionStrategy {
@Override
public Order applyPromotion(Order order) {
order.addGift(new Gift("促销赠品"));
return order;
}
}
促销引擎可以根据用户类型、活动时间等条件自动组合多种策略,实现复杂的促销逻辑。
7.2 多格式报表导出
另一个典型案例是报表导出系统,支持多种格式(PDF、Excel、CSV):
java复制public interface ExportStrategy {
byte[] export(ReportData data);
}
public class PdfExportStrategy implements ExportStrategy {
@Override
public byte[] export(ReportData data) {
// PDF导出逻辑
}
}
public class ExcelExportStrategy implements ExportStrategy {
@Override
public byte[] export(ReportData data) {
// Excel导出逻辑
}
}
public class ReportExporter {
private ExportStrategy strategy;
public void setStrategy(ExportStrategy strategy) {
this.strategy = strategy;
}
public byte[] exportReport(ReportData data) {
return strategy.export(data);
}
}
这种设计让新增导出格式变得非常简单,而且各导出逻辑互不干扰。
8. 策略模式的局限性与替代方案
8.1 何时不使用策略模式
虽然策略模式很强大,但并不适合所有场景:
- 简单条件逻辑:如果只有2-3个简单分支,if-else可能更直接
- 策略需要共享大量状态:策略之间需要频繁通信时,模式可能变得复杂
- 算法很少变化:如果算法基本固定不变,策略模式的灵活性优势无法体现
8.2 替代方案
在某些场景下,可以考虑以下替代方案:
- 枚举策略:对于简单固定的策略集合,可以使用枚举实现
java复制public enum SimpleShippingStrategy {
STANDARD {
public double calculate(double w, double d) { return w * 1.5 + d * 0.3; }
},
EXPRESS {
public double calculate(double w, double d) { return w * 2.5 + d * 0.5 + 10; }
};
public abstract double calculate(double weight, double distance);
}
-
规则引擎:对于极其复杂的业务规则,可以考虑使用Drools等规则引擎
-
函数式编程:如前所示,Java 8+可以使用函数式接口和Lambda简化策略实现
9. 设计原则与模式演进
9.1 策略模式体现的设计原则
策略模式是多个重要设计原则的典范:
- 开闭原则(OCP):可以扩展新策略而不修改现有代码
- 单一职责原则(SRP):每个策略类只负责一个算法实现
- 依赖倒置原则(DIP):高层模块依赖抽象接口,而非具体实现
- 组合优于继承:通过组合策略对象获得灵活性,而非通过继承
9.2 从策略模式到领域驱动设计
在复杂业务系统中,策略模式可以自然演进为领域驱动设计中的"策略"或"规格"模式:
java复制// 定价策略接口
public interface PricingStrategy {
Money calculatePrice(OrderLineItem item, Customer customer);
}
// VIP客户定价策略
public class VipPricingStrategy implements PricingStrategy {
@Override
public Money calculatePrice(OrderLineItem item, Customer customer) {
return item.basePrice().multiply(0.9); // VIP九折
}
}
// 批量采购定价策略
public class BulkPurchasePricingStrategy implements PricingStrategy {
@Override
public Money calculatePrice(OrderLineItem item, Customer customer) {
if (item.quantity() > 100) {
return item.basePrice().multiply(0.85); // 大批量85折
}
return item.basePrice();
}
}
这种设计让业务规则更加明确和可维护。
10. 代码重构实战:将条件逻辑转换为策略模式
让我们看一个实际的重构案例。假设有以下原始代码:
java复制public class ShippingCalculator {
public double calculateShipping(String customerType, double weight, double distance) {
if ("STANDARD".equals(customerType)) {
return weight * 1.5 + distance * 0.3;
} else if ("VIP".equals(customerType)) {
return 0;
} else if ("ENTERPRISE".equals(customerType)) {
return weight * 1.0 + distance * 0.2;
} else {
throw new IllegalArgumentException("未知客户类型");
}
}
}
重构步骤:
- 提取策略接口:
java复制public interface ShippingStrategy {
double calculate(double weight, double distance);
}
- 创建具体策略类:
java复制public class StandardShipping implements ShippingStrategy {
@Override
public double calculate(double weight, double distance) {
return weight * 1.5 + distance * 0.3;
}
}
public class VipShipping implements ShippingStrategy {
@Override
public double calculate(double weight, double distance) {
return 0;
}
}
public class EnterpriseShipping implements ShippingStrategy {
@Override
public double calculate(double weight, double distance) {
return weight * 1.0 + distance * 0.2;
}
}
- 重构上下文类:
java复制public class ShippingCalculator {
private final Map<String, ShippingStrategy> strategies;
public ShippingCalculator() {
this.strategies = new HashMap<>();
strategies.put("STANDARD", new StandardShipping());
strategies.put("VIP", new VipShipping());
strategies.put("ENTERPRISE", new EnterpriseShipping());
}
public double calculateShipping(String customerType, double weight, double distance) {
ShippingStrategy strategy = strategies.get(customerType);
if (strategy == null) {
throw new IllegalArgumentException("未知客户类型");
}
return strategy.calculate(weight, distance);
}
}
重构后的代码更加清晰、易于扩展,也更容易测试。新增客户类型时,只需添加新的策略类并在映射表中注册即可。
11. 策略模式在框架中的应用
11.1 Java集合框架中的策略模式
Java的Collections.sort()方法就是策略模式的经典应用:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用不同的比较策略
Collections.sort(names, String.CASE_INSENSITIVE_ORDER); // 策略1:不区分大小写
Collections.sort(names, Comparator.reverseOrder()); // 策略2:逆序
Collections.sort(names, (a, b) -> a.length() - b.length()); // 策略3:按长度
这里的Comparator接口就是策略接口,我们可以传入不同的比较策略来改变排序行为。
11.2 Spring框架中的策略模式
Spring框架中大量使用了策略模式,例如:
- ResourceLoader:根据资源路径前缀选择不同的资源加载策略
- HandlerMapping:根据请求选择不同的处理器策略
- ViewResolver:根据视图名称选择不同的视图解析策略
这些设计让Spring框架非常灵活,可以轻松扩展新的行为。
12. 性能优化与高级技巧
12.1 策略对象的复用
频繁创建策略对象可能带来性能开销。优化方法:
- 无状态策略:如果策略是无状态的,可以共享同一个实例
java复制public enum StatelessStrategies implements ShippingStrategy {
STANDARD {
public double calculate(double w, double d) { return w * 1.5 + d * 0.3; }
},
VIP {
public double calculate(double w, double d) { return 0; }
};
// 单例实例
public static final StatelessStrategies INSTANCE = valueOf("STANDARD");
}
- 对象池:对于有状态但创建成本高的策略,可以使用对象池
12.2 策略的懒加载
对于初始化成本高的策略,可以延迟加载:
java复制public class LazyStrategyHolder {
private Supplier<ShippingStrategy> strategySupplier;
private ShippingStrategy strategy;
public LazyStrategyHolder(Supplier<ShippingStrategy> supplier) {
this.strategySupplier = supplier;
}
public ShippingStrategy getStrategy() {
if (strategy == null) {
strategy = strategySupplier.get();
}
return strategy;
}
}
12.3 策略的并行处理
对于计算密集型策略,可以考虑并行处理:
java复制public class ParallelStrategyEvaluator {
public <T> T evaluateBest(List<Strategy<T>> strategies, T input) {
return strategies.parallelStream()
.map(s -> s.evaluate(input))
.max(Comparator.comparing(Result::getScore))
.orElseThrow().getResult();
}
}
13. 测试策略模式的代码
测试是策略模式的一大优势。以下是测试策略模式代码的最佳实践:
13.1 单元测试策略实现
每个策略实现应该有自己的测试类:
java复制public class StandardShippingTest {
@Test
public void testCalculate() {
ShippingStrategy strategy = new StandardShipping();
assertEquals(18.0, strategy.calculate(10, 10), 0.001);
}
}
13.2 测试策略选择逻辑
验证上下文类正确选择策略:
java复制public class ShippingContextTest {
@Test
public void testStrategySelection() {
ShippingContext context = new ShippingContext();
context.setStrategy(new StandardShipping());
assertEquals(18.0, context.executeCalculation(10, 10), 0.001);
}
}
13.3 集成测试
测试整个策略系统协同工作:
java复制public class ShippingSystemTest {
private ShippingCalculator calculator;
@Before
public void setUp() {
calculator = new ShippingCalculator();
}
@Test
public void testStandardCustomer() {
double result = calculator.calculateShipping("STANDARD", 10, 10);
assertEquals(18.0, result, 0.001);
}
@Test
public void testVipCustomer() {
double result = calculator.calculateShipping("VIP", 10, 10);
assertEquals(0.0, result, 0.001);
}
}
14. 策略模式在微服务架构中的应用
在微服务架构中,策略模式有更广泛的应用场景:
14.1 服务调用策略
java复制public interface ServiceInvocationStrategy {
Response invokeService(Request request);
}
// 重试策略
public class RetryStrategy implements ServiceInvocationStrategy {
@Override
public Response invokeService(Request request) {
int retries = 0;
while (retries < MAX_RETRIES) {
try {
return actualInvoke(request);
} catch (Exception e) {
retries++;
Thread.sleep(100 * retries);
}
}
throw new ServiceException("服务调用失败");
}
}
// 熔断策略
public class CircuitBreakerStrategy implements ServiceInvocationStrategy {
@Override
public Response invokeService(Request request) {
if (breaker.isOpen()) {
throw new CircuitBreakerOpenException();
}
try {
return actualInvoke(request);
} catch (Exception e) {
breaker.recordFailure();
throw e;
}
}
}
14.2 数据同步策略
在不同微服务间同步数据时,可以根据情况选择不同策略:
java复制public interface DataSyncStrategy {
void sync(Data data);
}
// 实时同步
public class RealtimeSync implements DataSyncStrategy {
@Override
public void sync(Data data) {
// 立即同步
}
}
// 批量同步
public class BatchSync implements DataSyncStrategy {
@Override
public void sync(Data data) {
// 加入批量队列
}
}
// 延迟同步
public class LazySync implements DataSyncStrategy {
@Override
public void sync(Data data) {
// 定时任务处理
}
}
15. 策略模式的未来演进
随着编程语言和范式的发展,策略模式也在不断演进:
15.1 函数式编程的影响
现代Java版本中,策略模式可以更加简洁地使用Lambda表达式实现:
java复制Map<String, Function<Order, BigDecimal>> strategies = new HashMap<>();
strategies.put("VIP", order -> order.getTotal().multiply(0.9));
strategies.put("NEW_USER", order -> order.getTotal().subtract(50));
strategies.put("PROMO", order -> order.getTotal().compareTo(200) > 0 ?
order.getTotal().subtract(30) : order.getTotal());
public BigDecimal applyDiscount(String type, Order order) {
return strategies.get(type).apply(order);
}
15.2 模式组合与创新
策略模式常与其他模式组合创新:
- 策略+装饰器:动态添加策略的额外行为
- 策略+责任链:按顺序尝试多个策略
- 策略+观察者:策略变更时通知相关组件
这些组合创造了更灵活的设计方案。
16. 从策略模式看软件设计哲学
策略模式体现了几个重要的软件设计哲学:
- 分离变与不变:将可能变化的算法封装起来,隔离稳定的上下文
- 面向接口编程:依赖抽象而非具体实现
- 单一职责:每个类只做一件事并做好
- 开闭原则:对扩展开放,对修改关闭
这些原则不仅适用于策略模式,也是良好软件设计的通用准则。
17. 个人实战经验分享
在我参与的一个金融项目中,我们使用策略模式处理不同类型的交易费用计算。最初系统只有几种简单费用类型,但随着业务发展,费用规则变得越来越复杂。通过策略模式重构后:
- 新增费用类型从平均2天工作量减少到2小时
- 费用计算错误减少了90%
- 单元测试覆盖率从40%提升到85%
- 不同费用类型的组合变得更加灵活
关键经验:
- 策略接口设计要足够通用,考虑未来扩展
- 策略命名要清晰反映其业务含义
- 为常用策略组合创建快捷方法
- 完善的文档和示例非常重要
18. 常见问题解答
Q1:策略模式会导致类爆炸吗?
A:确实可能。解决方法:
- 使用Lambda表达式简化简单策略
- 将相关策略组织到同一个包中
- 对于极其简单的策略,可以考虑使用枚举实现
Q2:如何在运行时动态加载策略?
A:可以通过以下几种方式:
- 使用ServiceLoader机制
- 结合Spring等DI框架
- 自定义策略注册表
Q3:策略之间如何共享数据?
A:推荐方式:
- 通过上下文对象共享
- 将共享数据作为策略方法参数
- 避免策略直接互相引用
Q4:如何处理策略执行失败?
A:建议策略方法明确声明可能抛出的异常,由上下文统一处理。或者返回包含结果和状态的结果对象。
19. 延伸学习资源
想要深入掌握策略模式,推荐以下资源:
-
书籍:
- 《Head First设计模式》第1章
- 《设计模式:可复用面向对象软件的基础》策略模式章节
- 《Effective Java》第21条:用函数对象表示策略
-
在线课程:
- Coursera的"Design Patterns"专项课程
- Udemy的"Java Design Patterns and Architecture"
-
开源项目:
- Spring框架中的各种策略实现
- Guava库中的策略式工具类
-
实践项目:
- 重构现有项目中的条件逻辑
- 实现一个支持多种算法的工具库
20. 总结与行动建议
策略模式是每个Java开发者都应该掌握的基本设计模式。它不仅能让你的代码更加灵活、更易维护,还能培养良好的设计思维。根据我的经验,建议你可以:
- 从小处开始:找出现有项目中的一个条件逻辑,用策略模式重构它
- 深入理解原理:不只是记住结构,要理解背后的设计原则
- 实践多种实现:尝试用传统类、枚举、Lambda等不同方式实现策略
- 观察框架应用:研究Spring等框架中策略模式的应用
- 持续重构改进:随着业务变化不断调整策略设计
记住,设计模式不是银弹,策略模式也不是所有条件逻辑的解决方案。但它确实为解决一类常见问题提供了优雅的方案。当你下次面对复杂的条件分支时,不妨考虑:"这里是否适合用策略模式?"
在实际项目中,我经常发现策略模式的价值不仅在于技术实现,更在于它促使我们思考如何更好地组织代码、分离关注点。这种设计思维比模式本身更重要。
