策略模式:优雅解耦算法的艺术
策略模式的定义与核心思想
策略模式属于行为型设计模式,允许在运行时选择算法的行为。它将算法封装在独立的类中,使它们可以互相替换。这种模式让算法的变化独立于使用算法的客户端。
核心思想是将算法与使用算法的对象解耦,通过定义一系列算法并将每个算法封装起来,让它们可以互相替换。策略模式让算法独立于客户端而变化。
策略模式的结构与组成
策略模式通常包含三个核心角色:
Context(上下文):持有一个策略类的引用,用策略对象来配置其行为。上下文通常包含一个接口让策略访问其数据。
Strategy(策略):定义所有支持的算法的公共接口。上下文使用这个接口调用具体策略定义的算法。
ConcreteStrategy(具体策略):实现策略接口的具体算法。
结构示例代码:
// 策略接口
interface Strategy {
int execute(int a, int b);
}
// 具体策略A
class ConcreteStrategyA implements Strategy {
public int execute(int a, int b) {
return a + b;
}
}
// 具体策略B
class ConcreteStrategyB implements Strategy {
public int execute(int a, int b) {
return a - b;
}
}
// 上下文
class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
策略模式的优点与适用场景
策略模式的主要优点包括:
- 算法可以自由切换
- 避免使用多重条件判断
- 扩展性良好,符合开闭原则
典型适用场景:
- 一个系统需要动态地在几种算法中选择一种
- 存在多种相似的行为,仅具体实现不同
- 需要封装算法相关的数据时
- 避免暴露复杂的与算法相关的数据结构
策略模式的实现示例
购物折扣策略示例:
// 折扣策略接口
interface DiscountStrategy {
double applyDiscount(double price);
}
// 普通会员折扣
class RegularDiscount implements DiscountStrategy {
public double applyDiscount(double price) {
return price * 0.9;
}
}
// VIP会员折扣
class VIPDiscount implements DiscountStrategy {
public double applyDiscount(double price) {
return price * 0.7;
}
}
// 购物车上下文
class ShoppingCart {
private DiscountStrategy discountStrategy;
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public double checkout(double total) {
return discountStrategy.applyDiscount(total);
}
}
策略模式与其他模式的比较
与状态模式的区别:
- 策略模式客户端知道所有策略,主动选择策略
- 状态模式的状态转换通常由状态类内部处理,客户端不感知
与命令模式的比较:
- 策略模式关注算法选择
- 命令模式关注请求的封装和参数化
与模板方法模式的区别:
- 策略模式使用对象组合
- 模板方法使用类继承
策略模式的最佳实践
实现策略模式时应注意:
- 将策略接口设计得尽可能通用,避免策略类膨胀
- 考虑使用工厂模式来创建策略对象
- 在策略无状态时可考虑实现为单例
- 使用依赖注入来配置策略
Java标准库中的策略模式应用:
Comparator接口是典型的策略模式LayoutManager在Swing中的使用ThreadPoolExecutor中的拒绝策略
策略模式的变体与扩展
策略模式的常见变体包括:
- 策略枚举:使用枚举实现简单策略
- 策略+工厂:结合工厂模式管理策略创建
- 策略+装饰器:为策略添加额外功能
- 策略+组合:组合多个策略形成新策略
Lambda表达式简化策略模式:
// 传统方式
context.setStrategy(new ConcreteStrategyA());
// Lambda方式
context.setStrategy((a, b) -> a + b);
策略模式的性能考量
策略模式的性能考虑因素:
- 策略对象创建开销
- 方法调用开销(虚方法调用)
- 内存占用(多策略实例)
- JIT优化可能性
优化建议:
- 无状态策略可共享实例
- 考虑策略对象缓存
- 对性能关键路径避免过度使用策略模式
BbS.okane122.info/PoSt/1121_289754.HtM
BbS.okane123.info/PoSt/1121_093520.HtM
BbS.okane124.info/PoSt/1121_584614.HtM
BbS.okane125.info/PoSt/1121_960885.HtM
BbS.okane126.info/PoSt/1121_157902.HtM
BbS.okane127.info/PoSt/1121_342914.HtM
BbS.okane128.info/PoSt/1121_022235.HtM
BbS.okane129.info/PoSt/1121_582159.HtM
BbS.okane130.info/PoSt/1121_312216.HtM
BbS.okane131.info/PoSt/1121_421602.HtM
BbS.okane122.info/PoSt/1121_364467.HtM
BbS.okane123.info/PoSt/1121_150791.HtM
BbS.okane124.info/PoSt/1121_083648.HtM
BbS.okane125.info/PoSt/1121_394355.HtM
BbS.okane126.info/PoSt/1121_976837.HtM
BbS.okane127.info/PoSt/1121_704785.HtM
BbS.okane128.info/PoSt/1121_912164.HtM
BbS.okane129.info/PoSt/1121_828324.HtM
BbS.okane130.info/PoSt/1121_823612.HtM
BbS.okane131.info/PoSt/1121_075961.HtM
BbS.okane132.info/PoSt/1121_046346.HtM
BbS.okane133.info/PoSt/1121_049169.HtM
BbS.okane134.info/PoSt/1121_617553.HtM
BbS.okane135.info/PoSt/1121_608749.HtM
BbS.okane136.info/PoSt/1121_501488.HtM
BbS.okane137.info/PoSt/1121_532035.HtM
BbS.okane138.info/PoSt/1121_909753.HtM
BbS.okane139.info/PoSt/1121_867249.HtM
BbS.okane140.info/PoSt/1121_527598.HtM
BbS.okane141.info/PoSt/1121_155147.HtM
BbS.okane132.info/PoSt/1121_253182.HtM
BbS.okane133.info/PoSt/1121_858784.HtM
BbS.okane134.info/PoSt/1121_740231.HtM
BbS.okane135.info/PoSt/1121_843527.HtM
BbS.okane136.info/PoSt/1121_409609.HtM
BbS.okane137.info/PoSt/1121_385124.HtM
BbS.okane138.info/PoSt/1121_122838.HtM
BbS.okane139.info/PoSt/1121_822371.HtM
BbS.okane140.info/PoSt/1121_423639.HtM
BbS.okane141.info/PoSt/1121_789566.HtM
BbS.okane132.info/PoSt/1121_573364.HtM
BbS.okane133.info/PoSt/1121_250266.HtM
BbS.okane134.info/PoSt/1121_161063.HtM
BbS.okane135.info/PoSt/1121_108510.HtM
BbS.okane136.info/PoSt/1121_809596.HtM
BbS.okane137.info/PoSt/1121_199845.HtM
BbS.okane138.info/PoSt/1121_135049.HtM
BbS.okane139.info/PoSt/1121_613168.HtM
BbS.okane140.info/PoSt/1121_407158.HtM
BbS.okane141.info/PoSt/1121_649514.HtM
BbS.okane132.info/PoSt/1121_864741.HtM
BbS.okane133.info/PoSt/1121_855732.HtM
BbS.okane134.info/PoSt/1121_957747.HtM
BbS.okane135.info/PoSt/1121_743450.HtM
BbS.okane136.info/PoSt/1121_276746.HtM
BbS.okane137.info/PoSt/1121_195964.HtM
BbS.okane138.info/PoSt/1121_749130.HtM
BbS.okane139.info/PoSt/1121_238458.HtM
BbS.okane140.info/PoSt/1121_530873.HtM
BbS.okane141.info/PoSt/1121_162003.HtM
BbS.okane132.info/PoSt/1121_963729.HtM
BbS.okane133.info/PoSt/1121_109179.HtM
BbS.okane134.info/PoSt/1121_657178.HtM
BbS.okane135.info/PoSt/1121_077811.HtM
BbS.okane136.info/PoSt/1121_535771.HtM
BbS.okane137.info/PoSt/1121_308015.HtM
BbS.okane138.info/PoSt/1121_274355.HtM
BbS.okane139.info/PoSt/1121_471357.HtM
BbS.okane140.info/PoSt/1121_922997.HtM
BbS.okane141.info/PoSt/1121_011232.HtM
BbS.okane132.info/PoSt/1121_663396.HtM
BbS.okane133.info/PoSt/1121_116645.HtM
BbS.okane134.info/PoSt/1121_292954.HtM
BbS.okane135.info/PoSt/1121_878448.HtM
BbS.okane136.info/PoSt/1121_155067.HtM
BbS.okane137.info/PoSt/1121_455170.HtM
BbS.okane138.info/PoSt/1121_194159.HtM
BbS.okane139.info/PoSt/1121_585875.HtM
BbS.okane140.info/PoSt/1121_387911.HtM
BbS.okane141.info/PoSt/1121_800889.HtM

查看3道真题和解析