魅力程序猿

  • 首页
  • Java
  • Android
  • APP
    • 扑克计分器
    • Video Wallpaper
  • 联系我
  • 关于我
  • 资助
道子
向阳而生
  1. 首页
  2. AI技术
  3. 正文

GoF设计模式——策略模式

2026年6月24日 10点热度 0人点赞 0条评论

📰 来源: 博客园


本文是【GoF设计模式】系列第14篇,更多内容欢迎关注公众号:咖啡八杯

电商网站结算时常常要算优惠:新用户满减、不同等级会员打折、节日活动满减。最直觉的写法是把所有规则塞进一个方法里用 if-else 区分:

class Cashier {
    public int calc(int total, String type) {
        if ("打九折".equals(type)) {
            return (int) (total * 0.9);
        } else if ("满300减40".equals(type)) {
            return total >= 300 ? total - 40 : total;
        } else {
            return total;
        }
    }
}

这种写法很快就会失控:每加一种优惠就要往 if-else 里塞分支,Cashier 被迫认识所有规则;规则一改,核心代码跟着动。分支越堆越多,最后谁也不敢碰这块代码。

策略模式解决的就是这个"同一件事有多种做法,做法还会不断增加"的问题。把每种做法封装成独立的策略类,Cashier 只管持有策略、在结算时调用,需要哪种优惠就注入哪种,互不干扰。

策略模式(Strategy Pattern)是一种行为型设计模式,核心思想是定义一系列算法,将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户端。

这些算法完成的是相同的工作,只是实现不同。客户端在运行时选择不同的具体策略,而不必修改自身代码——新增算法只需添加新策略类,符合开闭原则。

策略模式包含三个角色:

  • Strategy(策略接口):定义所有支持的算法的公共接口
  • ConcreteStrategy(具体策略):实现策略接口,提供具体的算法实现
  • Context(上下文):持有策略引用,负责业务数据管理和流程编排,在适当时机调用策略方法
    image
  • 图中各类之间的关系:ConcreteStrategyA、ConcreteStrategyB 实现 Strategy 接口,Context 持有一个 Strategy 引用,客户端面向 Context 编程——客户端和具体策略之间没有直接依赖,新增策略时 Context 无需改动。

    可以把策略模式想象成餐厅点菜:顾客(客户端)跟服务员(Context)说"来一份辣的菜",服务员不自己下厨,而是把需求转交给后厨对应的厨师(具体策略)。厨师换一道菜的做法,服务员和顾客完全不用变;后厨新招一个川菜师傅(新增策略),服务员只要会喊单就行。

    GoF 的标准实现中,Context 不是简单的转发层,它承担着业务数据管理和流程编排的职责。策略接口只定义纯算法契约,Context 负责将业务数据"翻译"成算法需要的参数。

    // 策略接口:定义算法的公共契约
    interface Strategy {
        public void algorithm();
    }
    
    // 具体策略 A
    class ConcreteStrategyA implements Strategy {
        public void algorithm() {
            System.out.println("策略 A 的算法实现");
        }
    }
    
    // 具体策略 B
    class ConcreteStrategyB implements Strategy {
        public void algorithm() {
            System.out.println("策略 B 的算法实现");
        }
    }
    
    // 上下文:持有策略引用,适当时机调用策略方法
    class Context {
        private Strategy strategy;
    
        public Context(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public void setStrategy(Strategy strategy) {
            this.strategy = strategy;
        }
    
        public void executeStrategy() {
            // Context 可以在调用策略前后做预处理/后处理
            strategy.algorithm();
        }
    }
    
    // 客户端代码
    Context context = new Context(new ConcreteStrategyA());
    context.executeStrategy();  // 使用策略 A
    
    context.setStrategy(new ConcreteStrategyB());
    context.executeStrategy();  // 切换为策略 B
    

    实现思想:Context 持有策略引用,业务流程由 Context 编排,具体算法委托给策略执行,运行时通过 setStrategy 动态切换。

    引入一个具体场景:商场收银支持无优惠、打九折、满减三种结算方式。用策略模式实现,Context 负责管理购物车和计算总价,策略只负责根据总价算优惠。

    // 策略接口:根据总价计算应付金额
    interface Strategy {
    public int algorithm(int price);
    }

    // 具体策略:无优惠
    class NormalStrategy implements Strategy {
    public int algorithm(int price) {
    return price;
    }
    }

    // 具体策略:打九折
    class DiscountStrategy implements Strategy {
    public int algorithm(int price) {
    return (int) (price * 0.9);
    }
    }

    // 具体策略:满减(满100减10,满200减25,满300减40,取最大满足档位)
    class FullReductionStrategy implements Strategy {
    public int algorithm(int price) {
    if (price >= 300) return price - 40;
    if (price >= 200) return price - 25;
    if (price >= 100) return price - 10;
    return price;
    }
    }

    // Context:管理购物车(数据总线)+ 计算总价(流程编排)+ 应用策略
    class CashierContext {
    private Strategy strategy;
    private List<Integer> prices = new ArrayList<>();

    public void setStrategy(Strategy strategy) {
    this.strategy = strategy;
    }

    public void addItem(int price) {
    prices.add(price);
    }

    public void checkout() {
    // 1. Context 负责


    🔗 原文链接: 点击阅读原文

    标签: AI 人工智能 技术博客
    最后更新:2026年6月24日

    daozi

    这个人很懒,什么都没留下

    点赞
    < 上一篇

    文章评论

    您需要 登录 之后才可以评论
    搜索
    联系方式

    QQ群:179730949
    QQ群:114559024
    欢迎您加入Android大家庭
    本人QQ:136049925

    赐我一丝安慰
    给我一点鼓励

    COPYRIGHT © 2023 魅力程序猿. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    豫ICP备15000477号