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

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端登录认证逻辑
	        ......
        });
    }

   
}

理论参考

相关推荐
m0_6355022017 分钟前
设计模式之单例模式
单例模式·设计模式
java_heartLake4 小时前
设计模式之单例模式
java·单例模式·设计模式
努力编程的阿伟20 小时前
二十三种设计模式之适配器模式
设计模式·适配器模式
蔚一1 天前
Java设计模式—面向对象设计原则(六) ----->合成复用原则(CRP) (完整详解,附有代码+案例)
xml·java·开发语言·设计模式·intellij-idea·合成复用原则
ok!ko1 天前
设计模式之建造者模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·建造者模式
Hcoco_me1 天前
面试爱考 | 设计模式
java·c++·设计模式·面试
血不热了1 天前
Qt:懒汉单例(附带单例使用和内存管理)
开发语言·qt·设计模式
潘多编程1 天前
通过Java设计模式提高业务流程灵活性的策略
java·单例模式·设计模式
努力编程的阿伟2 天前
二十三种设计模式之建造者模式(类比汽车制造厂好理解一些)
设计模式·建造者模式
J老熊2 天前
Java设计模式之责任链模式详细讲解和案例示范
java·设计模式·面试·系统架构·责任链模式·uml