策略模式:优雅解耦算法的艺术

策略模式的定义与核心思想

策略模式属于行为型设计模式,允许在运行时选择算法的行为。它将算法封装在独立的类中,使它们可以互相替换。这种模式让算法的变化独立于使用算法的客户端。

核心思想是将算法与使用算法的对象解耦,通过定义一系列算法并将每个算法封装起来,让它们可以互相替换。策略模式让算法独立于客户端而变化。

策略模式的结构与组成

策略模式通常包含三个核心角色:

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

#牛客AI配图神器#

全部评论

相关推荐

09-25 00:00
已编辑
电子科技大学 Java
球球与墩墩:这不是前端常考的对象扁平化吗,面试官像是前端出来的 const flattern = (obj) => { const res = {}; const dfs = (curr, path) => { if(typeof curr === 'object' && curr !== null) { const isArray = Array.isArray(curr); for(let key in curr) { const newPath = path ? isArray ? `${path}[${key}]` : `${path}.${key}` : key; dfs(curr[key], newPath); } } else { res[path] = curr } } dfs(obj); return res; }
查看3道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务