卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与面向对象

  • 集合

  • 异常

  • 字符串

  • JVM

  • 并发与多线程

  • JDK

  • Spring

  • 设计模式

    • 单例模式
    • 工厂模式
    • 建造者模式
    • 代理模式
    • 策略模式
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识图解
      • 使用场景
      • 知识扩展
    • 装饰器模式
    • 观察者模式

# 策略模式

# 简要回答

  • 策略模式(Strategy Pattern)是行为型设计模式,它定义了一系列算法,将每个算法都封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户,也就是说这些算法完成的功能类型和对外接口是一样的,只是不同的策略引起环境角色表现出不同的行为。
  • 优点:使用策略模式可以替代使用if...else或者switch...case语句,降低代码编写的复杂度,提高代码的可维护性。
  • 缺点:需要定义大量的策略类,且每个策略类都要提供给客户端,只适用于客户端知道所有策略类的情况。

# 详细回答

  • 策略模式主要由上下文、策略接口和具体策略类组成。Context类是用来操作策略的上下文环境类,持有抽象策略的引用,通过多态传进来不同的具体策略来调用不同策略的方法;策略接口定义了算法的接口或抽象类,声明所有具体策略必须实现的方法;具体的策略类实现了这个接口,实现具体算法的封装;
  • 实现策略模式的步骤:
    1. 定义一个策略接口,声明算法的抽象方法。
    2. 创建具体的策略类,实现策略接口并封装具体的算法。
    3. 创建环境类,包含对策略接口的引用以及一个用于设置具体对象的方法。
    4. 在客户端中创建环境类的对象,并调用其方法来执行具体的算法。

# 代码示例

  1. 下面是一个简单的策略模式的示例,假设有一个商场销售系统,根据不同的促销策略计算最终价格:
// 策略接口
public interface PricingStrategy {
    double calculatePrice(double price);
}

// 具体策略类:无折扣
public class NoDiscountStrategy implements PricingStrategy {
    @Override
    public double calculatePrice(double price) {
        return price;
    }
}

// 具体策略类:打九折
public class DiscountStrategy implements PricingStrategy {
    @Override
    public double calculatePrice(double price) {
        return price * 0.9;
    }
}

// 具体策略类:满减
public class CashbackStrategy implements PricingStrategy {
    @Override
    public double calculatePrice(double price) {
        if (price >= 200) {
            return price - 50;
        } else {
            return price;
        }
    }
}

// 环境类
public class ShoppingCart {
    private PricingStrategy pricingStrategy;

    public void setPricingStrategy(PricingStrategy pricingStrategy) {
        this.pricingStrategy = pricingStrategy;
    }

    public double checkout(double totalPrice) {
        return pricingStrategy.calculatePrice(totalPrice);
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        // 选择无折扣策略
        cart.setPricingStrategy(new NoDiscountStrategy());
        double price1 = cart.checkout(100);
        System.out.println("Total Price: " + price1); // 输出:Total Price: 100.0

        // 选择打九折策略
        cart.setPricingStrategy(new DiscountStrategy());
        double price2 = cart.checkout(100);
        System.out.println("Total Price: " + price2); // 输出:Total Price: 90.0

        // 选择满减策略
        cart.setPricingStrategy(new CashbackStrategy());
        double price3 = cart.checkout(200);
        System.out.println("Total Price: " + price3); // 输出:Total Price: 150.0
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

# 知识图解

  1. 策略模式结构图 image

# 使用场景

  1. 当需要动态切换算法时,可以使用策略模式。
  2. 如果代码中有多个条件语句,存在复杂条件判断时,可以使用策略模式简化代码。
  3. 使用策略模式可以避免与算法相关的数据结构暴露,只需使用抽象接口调用,无需知道实现细节。
  4. 如果有许多相关的类仅仅是行为不同,那么可以使用策略模式。

# 知识扩展

  1. 面试官可能追问:
  • Q1:如何避免策略类过多的问题?
    • 解决策略模式策略类过多的问题,核心有三层优化思路,首先最常用的是结合简单工厂模式,把所有策略对象的创建逻辑统一封装到策略工厂中,由工厂根据业务标识匹配并返回对应策略对象,客户端只需传入标识即可使用,无需感知所有策略类;其次进阶优化是在工厂中用Map容器做策略缓存,把策略标识和策略实例做键值对映射,项目启动时初始化存入 Map,获取策略时直接 O(1) 查询,彻底去掉 if-else/switch 分支判断,同时满足开闭原则;最后从根源上避免类膨胀,是对策略做复用与参数化抽离,很多策略类只是参数不同、核心逻辑一致,比如不同满减规则、不同计费标准,这种场景无需新建类,只需把可变参数抽离出来,通过构造器或方法传入策略类,一个策略类即可适配多套规则,从根本上减少策略类的数量。
Last Updated: 3/10/2026, 6:08:48 PM

← 代理模式 装饰器模式 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪