java 设计模式 策略模式

简介

策略模式(Strategy Pattern)是一种行为设计模式,旨在定义一系列算法,并将每一个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端。换句话说,策略模式通过将不同的算法封装成独立的策略类,允许在运行时动态选择不同的策略,而无需修改客户端代码。

策略模式的组成部分

Context(上下文类):上下文类持有一个策略对象,并提供一个接口来让客户端设置或更改策略。上下文通常会在需要时委托策略类来执行具体的算法。

Strategy(策略接口):策略接口定义了一个共同的接口,所有具体策略类都需要实现这个接口。

ConcreteStrategy(具体策略类):具体策略类实现了策略接口,封装了具体的算法或行为。

下面解释最常用的写法

通用实现

场景

例如现在公司在做一个支付平台,需要对接很多家第三方公司,例如支付宝,拉卡拉,通联之类的

第一步定义策略类接口

可以理解为这是对支付的一个策略,因为需要根据客户端创建类型创建不同的支付策略

java 复制代码
public interface PaymentStrategy {
    void pay(double amount);
}

第二步创建具体策略类

例如下面就创建了银行卡支付,支付宝支付,微信支付三个策略类,继承PaymentStrategy接口

java 复制代码
// 信用卡支付
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Using Credit Card to pay: " + amount);
    }
}

// 支付宝支付
public class AlipayPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Using Alipay to pay: " + amount);
    }
}

// 微信支付
public class WeChatPayment implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("Using WeChat Pay to pay: " + amount);
    }
}

第三步创建上下文类,来转发到对应的具体策略类实现,一般来说就是设置策略(向上转型),然后执行支付对应到不同的实现类

java 复制代码
public class PaymentContext {
    private PaymentStrategy paymentStrategy;

    // 设置策略
    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    // 执行支付
    public void executePayment(double amount) {
        if (paymentStrategy == null) {
            System.out.println("No payment strategy set!");
            return;
        }
        paymentStrategy.pay(amount);
    }
}

第四步客户端调用,这样客户端就只需要创建对应的支付方式就行了

java 复制代码
public class Main {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext();

        // 设置为信用卡支付策略
        context.setPaymentStrategy(new CreditCardPayment());
        context.executePayment(100.0);

        // 设置为支付宝支付策略
        context.setPaymentStrategy(new AlipayPayment());
        context.executePayment(200.0);

        // 设置为微信支付策略
        context.setPaymentStrategy(new WeChatPayment());
        context.executePayment(300.0);
    }
}

简略实现

这里我感觉策略模式实际上就是根据不同的情况,再程序运行的时候动态切换方式

那么有个场景 在登录的时候有多种登录方式,这时候下面这种方式创建的,是不是也是策略模式呢

java 复制代码
@Component
public class LoginStrategyFactory {
    
    private final Map<Integer, LoginStrategy> strategyMap = new ConcurrentHashMap<>();
    
    public LoginStrategyFactory(Map<String, LoginStrategy> strategyMap) {
        strategyMap.values().forEach(strategy -> 
            this.strategyMap.put(strategy.getLoginType().getLoginType(), strategy));
    }
    
    public LoginStrategy getStrategy(Integer loginType) {
        return strategyMap.get(loginType);
    }
} 

这里登录的时候根据客户端传过来的登录类型(账号密码还是短信,或者其他的)来获取不同的对象

java 复制代码
    public TokenVO login(LoginRequest loginRequest) {
        LoginStrategy strategy = loginStrategyFactory.getStrategy(loginRequest.getAuthType());
        if (Objects.isNull(strategy)) {
            throw ExFactory.bizException(PaymentError.UNSUPPORTED_AUTH_TYPE);
        }
        return loginProcessor.login(loginRequest, strategy);
    }
相关推荐
vx1_Biye_Design10 分钟前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design11 分钟前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
hay_lee30 分钟前
Spring AI实现对话聊天-流式输出
java·人工智能·ollama·spring ai
Hx_Ma1635 分钟前
SpringBoot数据源自动管理
java·spring boot·spring
SunnyDays101136 分钟前
Java 高效实现 CSV 转 Excel
java·csv转excel
starfire_hit37 分钟前
JAVAWEB根据前台请求获取用户IP
java·服务器·网络
fengxin_rou39 分钟前
[Redis从零到精通|第四篇]:缓存穿透、雪崩、击穿
java·redis·缓存·mybatis·idea·多线程
像少年啦飞驰点、42 分钟前
从零开始学 RabbitMQ:小白也能懂的消息队列实战指南
java·spring boot·微服务·消息队列·rabbitmq·异步编程
宠友信息1 小时前
2025社交+IM及时通讯社区APP仿小红书小程序
java·spring boot·小程序·uni-app·web app
java1234_小锋1 小时前
Java高频面试题:Spring和SpringBoot的关系和区别?
java·spring boot·spring