设计模式实际应用-策略模式

1、使用场景

关键业务中使用大量的if else 判断,此时可以使用策略模式进行优化

2、应用

场景1:当入参为1时,执行计费的逻辑,入参为2时执行退费的逻辑,需要入参和出参的

java 复制代码
// 计费
if (chargeOrReturnReq.getCalcMode() == 1) {
		String useCode = doLowCharge(detailsList);
....
}
// 退费
if (chargeOrReturnReq.getCalcMode() == 2) {
	String refundCode = doLowRefund(detailsList);
 ....
}

使用策略模式优化

优化后此处代码为

java 复制代码
// Map.get方法根据key获取对应的策略,key = 1计费 key=2 退费,返回的是对应计费或者退费的方法
Function<List<HisLowChargeDetails>, List<HisLowChargeOrReturnRes>> listStringFunction = DO_LOW_CHARGE_OR_REFUND_STRATEGY.get(chargeOrReturnReq.getCalcMode());
// 方法.apply 调用具体的计费/退费方法并获取返回值
List<HisLowChargeOrReturnRes> resOneList = listStringFunction.apply(detailsList);

策略类

java 复制代码
package com.miyite.consumables.modules.external.strategy;


import cn.hutool.extra.spring.SpringUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class HisChargeOrRefundStrategy {
	// 业务中需要的依赖注入
    private static HisChargeItemDao hisChargeItemDao;
    private static HisLowChargeDetailsDao hisLowChargeDetailsDao;
    private static HwfRefundService hwfRefundService;
    private static HwfUseDetailsDao hwfUseDetailsDao;
    private static HwfWarehouseInDetailsDao hwfWarehouseInDetailsDao;
    private static HwfUseService hwfUseService;
    private static void setContext() {
    	// 使用hutool类获取Bean对象
        hisChargeItemDao = SpringUtil.getBean(HisChargeItemDao.class);
        hisLowChargeDetailsDao = SpringUtil.getBean(HisLowChargeDetailsDao.class);
        hwfRefundService = SpringUtil.getBean(HwfRefundService.class);
        hwfUseDetailsDao = SpringUtil.getBean(HwfUseDetailsDao.class);
        hwfWarehouseInDetailsDao = SpringUtil.getBean(HwfWarehouseInDetailsDao.class);
        // 使用hutool类获取Bean对象
        hwfUseService = SpringUtil.getBean(HwfUseService.class);
    }

	// 策略的Map集合 value是一个方法 方法中第一个调用本策略的 是入参  第二个是出参
    public static final Map<Integer, Function<List<HisLowChargeDetails>, List<HisLowChargeOrReturnRes>>> DO_LOW_CHARGE_OR_REFUND_STRATEGY = new HashMap<>();



    static {

        /* 计费策略 */
        DO_LOW_CHARGE_OR_REFUND_STRATEGY.put(1, HisChargeOrRefundStrategy::doLowCharge);

        /* 退费策略 */
        DO_LOW_CHARGE_OR_REFUND_STRATEGY.put(2,HisChargeOrRefundStrategy::doLowRefund);
    }

    private static List<HisLowChargeOrReturnRes> doLowCharge(List<HisLowChargeDetails> detailsList) {
        setContext();
        ..计费业务..
       
    }
    private static List<HisLowChargeOrReturnRes> doLowRefund(List<HisLowChargeDetails> detailsList) {
        setContext();
       ..退费业务..
    }



}

场景2 登录方式有PC端登录 PDA登录,有多个入参,并且不需要出参的

1、调用本策略的代码

java 复制代码
// 执行终端身份认证
TerminalAuthentication terminalAuthentication = TERMINAL_STRATEGY.get(loginInfo.getSource());
        
terminalAuthentication.executeAuthentication(loginInfo, request, response, chain);

2、策略模式接口

java 复制代码
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 终端认证
 */
@FunctionalInterface
public interface TerminalAuthentication {
    /**
     * 执行认证
     *
     * @param loginInfo 登录信息
     * @param request   请求对象
     * @param response  响应对象
     * @param chain     过滤器链
     */
    void executeAuthentication(LoginInfo loginInfo, HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException;
}

3、策略模式类

java 复制代码
import com.auth0.jwt.interfaces.Claim;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.medical.nurse.cache.keys.SecurityRedisKey.LOGINED_ITEM_PERMISSION;
import static com.medical.nurse.cache.keys.SecurityRedisKey.LOGINED_ITEM_TOKEN;

/**
 * 终端认证策略
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class TerminalAuthenticationStrategy {
    /**
     * 定义不同终端的认证实现
     */
    public static final Map<LoginSource, TerminalAuthentication> TERMINAL_STRATEGY = new HashMap<>();

    /* 初始化终端认证策略 */
    static {
        /* PC端认证策略 */
        TERMINAL_STRATEGY.put(LoginSource.PC, (loginInfo, request, response, chain) -> {
	        // pc端登录认证逻辑
	        ......
           
        });

        /* PDA端认证策略 */
        TERMINAL_STRATEGY.put(LoginSource.PDA, (loginInfo, request, response, chain) -> {
           	  // pc端登录认证逻辑
	        ......
        });
    }

   
}

理论参考

相关推荐
晨米酱7 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机12 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机13 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机13 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机13 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤13 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴2 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式