JAVA中六种策略模式的实现方式(附代码示例和适用场景)

 更新时间:2026年01月30日 10:20:19   作者:海阔天空在前走  
策略模式是一种行为模式,也是替代大量ifelse的利器,它所能帮你解决的是场景,一般是具有同类可替代的行为逻辑算法场景,这篇文章主要介绍了JAVA中六种策略模式实现方式的相关资料,需要的朋友可以参考下

前言

在 Java 中,策略模式的核心是定义算法族、封装算法、动态切换,其实现方式主要围绕 “策略的定义、创建、选择” 展开,根据场景复杂度和技术选型,常见有以下 6 种实现方式,附代码示例和适用场景:

一、基础实现:接口 + 实现类(经典方式)

最标准的实现,通过接口定义策略契约,多个实现类封装不同算法,客户端通过注入或选择不同实现类切换策略。

代码示例

// 1. 策略接口(定义契约)
public interface PaymentStrategy {
    // 策略核心方法:支付
    boolean pay(double amount);
    // 获取策略名称
    String getStrategyName();
}

// 2. 具体策略1:支付宝支付
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + "元");
        return true; // 模拟支付成功
    }

    @Override
    public String getStrategyName() {
        return "alipay";
    }
}

// 3. 具体策略2:微信支付
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用微信支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyName() {
        return "wechat";
    }
}

// 4. 策略上下文(封装策略,对外提供统一接口)
public class PaymentContext {
    private PaymentStrategy strategy;

    // 构造器注入策略
    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    // 动态切换策略
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    // 客户端调用入口
    public boolean executePayment(double amount) {
        return strategy.pay(amount);
    }
}

// 5. 客户端使用
public class Client {
    public static void main(String[] args) {
        // 选择支付宝策略
        PaymentContext context = new PaymentContext(new AlipayStrategy());
        context.executePayment(100);

        // 动态切换为微信策略
        context.setStrategy(new WechatPayStrategy());
        context.executePayment(200);
    }
}

适用场景

  • 策略数量固定、变化不频繁(如支付方式、排序算法)。
  • 需明确暴露所有策略,允许客户端直接选择。

二、枚举实现(简化策略管理)

用枚举封装所有策略,利用枚举的 “单例特性” 和 “天然分组” 优势,减少类冗余,简化策略选择。

代码示例

// 1. 枚举策略(实现策略逻辑)
public enum PaymentStrategyEnum {
    // 支付宝策略
    ALIPAY {
        @Override
        public boolean pay(double amount) {
            System.out.println("枚举-支付宝支付:" + amount + "元");
            return true;
        }
    },
    // 微信支付策略
    WECHAT {
        @Override
        public boolean pay(double amount) {
            System.out.println("枚举-微信支付:" + amount + "元");
            return true;
        }
    };

    // 策略核心方法(枚举抽象方法)
    public abstract boolean pay(double amount);
}

// 2. 客户端使用(直接通过枚举选择策略)
public class Client {
    public static void main(String[] args) {
        // 根据枚举值选择策略
        PaymentStrategyEnum.ALIPAY.pay(100);
        PaymentStrategyEnum.WECHAT.pay(200);

        // 支持动态传入策略(如从配置文件读取)
        String strategyName = "ALIPAY"; // 可来自配置
        PaymentStrategyEnum strategy = Enum.valueOf(PaymentStrategyEnum.class, strategyName);
        strategy.pay(300);
    }
}

适用场景

  • 策略数量少、逻辑简单(如状态判断、固定规则)。
  • 无需动态扩展策略(枚举不可动态新增)。

三、工厂模式 + 策略模式(解耦策略创建)

通过工厂类封装策略的创建逻辑,客户端无需关注策略的实例化细节,只需传入标识即可获取对应策略,适合策略较多的场景。

代码示例

// 1. 策略接口(同基础实现)
public interface PaymentStrategy {
    boolean pay(double amount);
    String getStrategyCode();
}

// 2. 具体策略(同基础实现:AlipayStrategy、WechatPayStrategy)

// 3. 策略工厂(封装策略创建)
public class PaymentStrategyFactory {
    // 缓存策略实例(单例)
    private static final Map<String, PaymentStrategy> STRATEGY_MAP = new HashMap<>();

    // 静态初始化:注册所有策略
    static {
        STRATEGY_MAP.put("alipay", new AlipayStrategy());
        STRATEGY_MAP.put("wechat", new WechatPayStrategy());
    }

    // 禁止外部实例化
    private PaymentStrategyFactory() {}

    // 根据标识获取策略
    public static PaymentStrategy getStrategy(String strategyCode) {
        PaymentStrategy strategy = STRATEGY_MAP.get(strategyCode);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式:" + strategyCode);
        }
        return strategy;
    }

    // 扩展:动态注册新策略(支持热更新)
    public static void registerStrategy(String code, PaymentStrategy strategy) {
        STRATEGY_MAP.put(code, strategy);
    }
}

// 4. 客户端使用
public class Client {
    public static void main(String[] args) {
        // 从工厂获取策略(无需手动new)
        PaymentStrategy alipay = PaymentStrategyFactory.getStrategy("alipay");
        alipay.pay(100);

        PaymentStrategy wechat = PaymentStrategyFactory.getStrategy("wechat");
        wechat.pay(200);

        // 动态注册新策略(如新增银联支付)
        PaymentStrategyFactory.registerStrategy("unionpay", new UnionPayStrategy());
        PaymentStrategyFactory.getStrategy("unionpay").pay(300);
    }
}

// 新增策略:银联支付(无需修改工厂核心逻辑)
class UnionPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("使用银联支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "unionpay";
    }
}

适用场景

  • 策略数量多(如 10+),需要统一管理创建逻辑。
  • 客户端只需通过标识(如字符串、枚举)选择策略,无需关注实现。

四、注解 + 反射(动态扫描策略)

通过自定义注解标记策略类,程序启动时扫描所有带注解的策略并注册到工厂,支持 “无侵入式扩展”(新增策略无需修改工厂代码)。

代码示例

// 1. 自定义策略注解(标记策略标识)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PaymentStrategyAnnotation {
    String code(); // 策略唯一标识
}

// 2. 策略接口(同基础实现)
public interface PaymentStrategy {
    boolean pay(double amount);
}

// 3. 具体策略(用注解标记)
@PaymentStrategyAnnotation(code = "alipay")
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("注解-支付宝支付:" + amount + "元");
        return true;
    }
}

@PaymentStrategyAnnotation(code = "wechat")
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("注解-微信支付:" + amount + "元");
        return true;
    }
}

// 4. 策略工厂(反射扫描注解策略)
public class AnnotationStrategyFactory {
    private static final Map<String, PaymentStrategy> STRATEGY_MAP = new HashMap<>();

    // 初始化:扫描指定包下的所有策略
    static {
        try {
            // 扫描com.example.strategy包下的所有类
            Reflections reflections = new Reflections("com.example.strategy");
            // 获取所有带@PaymentStrategyAnnotation注解的类
            Set<Class<?>> strategyClasses = reflections.getTypesAnnotatedWith(PaymentStrategyAnnotation.class);

            // 实例化并注册策略
            for (Class<?> clazz : strategyClasses) {
                PaymentStrategyAnnotation annotation = clazz.getAnnotation(PaymentStrategyAnnotation.class);
                String code = annotation.code();
                PaymentStrategy strategy = (PaymentStrategy) clazz.newInstance();
                STRATEGY_MAP.put(code, strategy);
            }
        } catch (Exception e) {
            throw new RuntimeException("策略初始化失败", e);
        }
    }

    // 获取策略
    public static PaymentStrategy getStrategy(String code) {
        return STRATEGY_MAP.getOrDefault(code, () -> {
            System.out.println("默认策略:支付失败");
            return false;
        });
    }
}

// 5. 客户端使用(依赖Reflections库,需导入依赖)
public class Client {
    public static void main(String[] args) {
        AnnotationStrategyFactory.getStrategy("alipay").pay(100);
        AnnotationStrategyFactory.getStrategy("wechat").pay(200);
    }
}

依赖说明

需导入反射扫描库(Maven):

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.10.2</version>
</dependency>

适用场景

  • 大型项目,策略频繁新增(如插件化架构)。
  • 追求 “开闭原则”,新增策略无需修改现有代码。

五、Lambda 表达式(简化无状态策略)

对于无状态、逻辑简单的策略,可直接用 Lambda 表达式实现策略接口,无需创建单独的实现类,简化代码。

代码示例

// 1. 函数式策略接口(仅含一个抽象方法)
@FunctionalInterface
public interface PaymentStrategy {
    boolean pay(double amount);
}

// 2. 策略上下文(同基础实现)
public class PaymentContext {
    private PaymentStrategy strategy;

    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public boolean execute(double amount) {
        return strategy.pay(amount);
    }
}

// 3. 客户端使用(Lambda直接实现策略)
public class Client {
    public static void main(String[] args) {
        // Lambda实现支付宝策略
        PaymentContext alipayContext = new PaymentContext(amount -> {
            System.out.println("Lambda-支付宝支付:" + amount + "元");
            return true;
        });
        alipayContext.execute(100);

        // Lambda实现微信策略
        PaymentContext wechatContext = new PaymentContext(amount -> {
            System.out.println("Lambda-微信支付:" + amount + "元");
            return true;
        });
        wechatContext.execute(200);

        // 甚至可以直接传递Lambda,无需上下文
        PaymentStrategy unionPay = amount -> {
            System.out.println("Lambda-银联支付:" + amount + "元");
            return true;
        };
        unionPay.pay(300);
    }
}

适用场景

  • 策略逻辑简单(1-3 行代码)、无状态(无需成员变量)。
  • 临时策略(仅使用一次),无需复用。

六、Spring 容器整合(依赖注入 + 自动装配)

在 Spring 项目中,利用 Spring 的 IOC 容器管理策略实例,通过@Autowired自动注入所有策略,结合MapList实现策略选择,无需手动创建工厂。

代码示例

// 1. 策略接口(同基础实现)
public interface PaymentStrategy {
    boolean pay(double amount);
    String getStrategyCode();
}

// 2. 具体策略(Spring组件)
@Component // 交给Spring管理
public class AlipayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("Spring-支付宝支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "alipay";
    }
}

@Component
public class WechatPayStrategy implements PaymentStrategy {
    @Override
    public boolean pay(double amount) {
        System.out.println("Spring-微信支付:" + amount + "元");
        return true;
    }

    @Override
    public String getStrategyCode() {
        return "wechat";
    }
}

// 3. 策略服务(Spring组件,自动注入所有策略)
@Service
public class PaymentService {
    // Spring会自动将所有PaymentStrategy实现类注入到Map中:key=beanName,value=策略实例
    @Autowired
    private Map<String, PaymentStrategy> strategyMap;

    // 或按策略code映射(自定义key)
    private Map<String, PaymentStrategy> codeToStrategyMap;

    // 初始化:将策略按code分组
    @PostConstruct
    public void init() {
        codeToStrategyMap = strategyMap.values().stream()
                .collect(Collectors.toMap(PaymentStrategy::getStrategyCode, s -> s));
    }

    // 执行策略
    public boolean executePayment(String strategyCode, double amount) {
        PaymentStrategy strategy = codeToStrategyMap.get(strategyCode);
        if (strategy == null) {
            throw new IllegalArgumentException("不支持的支付方式");
        }
        return strategy.pay(amount);
    }
}

// 4. 客户端使用(Spring环境)
@SpringBootApplication
public class StrategyApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(StrategyApplication.class, args);
        PaymentService paymentService = context.getBean(PaymentService.class);

        paymentService.executePayment("alipay", 100);
        paymentService.executePayment("wechat", 200);
    }
}

适用场景

  • Spring Boot/Spring MVC 项目(充分利用 Spring 的 IOC 特性)。
  • 策略需要依赖其他 Spring 组件(如@Autowired数据源、缓存等)。

六种实现方式对比

实现方式优点缺点适用场景
接口 + 实现类(经典)结构清晰、易理解策略多时有类爆炸问题策略少、变化不频繁
枚举实现代码简洁、无类冗余策略逻辑复杂时不适用,不可动态扩展策略少、逻辑简单
工厂 + 策略解耦创建逻辑、支持动态扩展新增策略需修改工厂注册代码策略较多、需要统一管理
注解 + 反射无侵入扩展、支持插件化依赖反射库、初始化开销略大大型项目、策略频繁新增
Lambda 表达式代码极简、无需创建类无状态、逻辑简单场景受限临时策略、简单逻辑
Spring 整合自动注入、支持依赖管理依赖 Spring 环境Spring 项目、策略需依赖其他组件

核心设计原则

无论哪种实现方式,都需遵循:

  1. 开闭原则:新增策略无需修改现有代码(枚举方式除外)。
  2. 单一职责:每个策略只负责一种算法,上下文只负责协调策略。
  3. 里氏替换:任何策略都可替换为其他实现,不影响客户端使用。

总结 

到此这篇关于JAVA中六种策略模式实现方式的文章就介绍到这了,更多相关JAVA策略模式实现方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解Java定时调度(Timer)机制

    深入理解Java定时调度(Timer)机制

    这篇文章主要介绍了深入理解Java定时调度(Timer)机制,本节我们主要分析 Timer 的功能。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Spring Cloud @EnableFeignClients注解的属性字段basePacka详解

    Spring Cloud @EnableFeignClients注解的属性字段basePacka详解

    这篇文章主要介绍了Spring Cloud @EnableFeignClients注解的属性字段basePacka详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 零基础写Java知乎爬虫之获取知乎编辑推荐内容

    零基础写Java知乎爬虫之获取知乎编辑推荐内容

    上篇文章我们拿百度首页做了个小测试,今天我们来个复杂的,直接抓取知乎编辑推荐的内容,小伙伴们可算松了口气,终于进入正题了,哈哈。
    2014-11-11
  • Java网络编程基础详解

    Java网络编程基础详解

    网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。本文介绍了一些网络编程基础的概念,并用Java来实现TCP和UDP的Socket的编程,来让读者更好的了解其原理
    2021-08-08
  • Java方法重写_动力节点Java学院整理

    Java方法重写_动力节点Java学院整理

    在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖,下文给大家介绍java方法重写及重写规则,一起学习吧
    2017-04-04
  • IDEA 2020 2全家桶安装激活超详细图文教程

    IDEA 2020 2全家桶安装激活超详细图文教程

    这篇文章主要介绍了IDEA-2020-2 全家桶安装激活超详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • Java实现计算一个月有多少天和多少周

    Java实现计算一个月有多少天和多少周

    这篇文章主要介绍了Java实现计算一个月有多少天和多少周,本文直接给出实例代码,需要的朋友可以参考下
    2015-06-06
  • 安全漏洞修复导致SpringBoot2.7与Springfox不兼容的伪命题解决

    安全漏洞修复导致SpringBoot2.7与Springfox不兼容的伪命题解决

    项目基于Spring Boot 2.5.2使用Springfox Swagger2生成API文档,因安全漏洞需升级至2.7.8,导致兼容问题,下面就来介绍一下问题解决,感兴趣的可以了解一下
    2025-06-06
  • Spring、SpringMvc和SpringBoot的区别及说明

    Spring、SpringMvc和SpringBoot的区别及说明

    Spring框架提供了全面的Java开发解决方案,核心包括IOC和AOP,SpringMvc作为其中的WEB层开发框架,通过复杂的XML配置管理前端视图和后台逻辑,SpringBoot则简化了配置,专注于微服务接口开发,支持嵌入式服务器,提高了开发效率
    2024-10-10
  • Java中Switch用法代码示例

    Java中Switch用法代码示例

    这篇文章主要介绍了Java中Switch用法代码示例,向大家分享了两段代码,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11

最新评论