策略模式代替IfElse和SwitchCase

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了策略模式代替IfElse和SwitchCase相关的知识,希望对你有一定的参考价值。

使用策略模式的原因

在项目的起始阶段通常需求还是很明确的,但是到了后期因为各种需求的叠加,会导致业务逻辑中存在一长串的if else或者switch case,长达10几个的if else容易让人看着眼花,不利于代码阅读。所以用策略模式去改善是非常有必要的。

策略模式使用demo

这里就拿订单状态来改造一波,原始代码如下

switch (orderInfoDO.getOrderStatus().toString())
    case "UNPAID":
        vo.setOrderStatusDescription("未支付");
        break;
    case "GRABBING":
        vo.setOrderStatusDescription("抢单中");
        break;
    case "DOING":
        vo.setOrderStatusDescription("进行中");
        break;
        。
        。
        。

使用策略模式

先设计一个接口

package com.xx.xx..strategy;

import com.xx.xx.enums.OrderStatus;

public interface OrderStatusStrategy 

    //获取订单状态枚举
    OrderStatus getOrderStatusEnum();

    //获取订单状态描述
    String getOrderStatusDescription();

    //解析参数,todo
    void reSolve(Object param);


未支付状态

package com.xx.xx.strategy;

import com.xx.xx.enums.OrderStatus;
import org.springframework.stereotype.Component;

@Component
public class UnpaidStatusStrategy implements OrderStatusStrategy

    @Override
    public OrderStatus getOrderStatusEnum() 
        return OrderStatus.UNPAID;
    

    @Override
    public String getOrderStatusDescription() 
        return "未支付";
    

    @Override
    public void reSolve(Object param) 

    

抢单中状态

package com.xx.xx.strategy;

import com.xx.xx.enums.OrderStatus;
import org.springframework.stereotype.Component;

@Component
public class GrabbingStatusStrategy implements OrderStatusStrategy

    @Override
    public OrderStatus getOrderStatusEnum() 
        return OrderStatus.GRABBING;
    

    @Override
    public String getOrderStatusDescription() 
        return "抢单中";
    

    @Override
    public void reSolve(Object param) 

    

以此类推
.
.
.

策略对外使用service

package com.xx.xx.strategy;

import com.xx.xx.enums.OrderStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
public class OrderStatusStrategyService implements ApplicationContextAware 

    private ApplicationContext applicationContext;

    private ConcurrentHashMap<OrderStatus, OrderStatusStrategy> orderStatusStrategyMap = new ConcurrentHashMap<>();


    public String getOrderStatusDescription(OrderStatus orderStatus)
        OrderStatusStrategy orderStatusStrategy = orderStatusStrategyMap.get(orderStatus);
        if(Objects.isNull(orderStatusStrategy))
            log.error("未获取到对应策略 orderStatus:, orderStatusStrategyMap.values:", orderStatus, orderStatusStrategyMap.keySet());
            return "";
        
        return orderStatusStrategy.getOrderStatusDescription();
    



    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
        this.applicationContext = applicationContext;
        Map<String, OrderStatusStrategy> strategyMap = this.applicationContext.getBeansOfType(OrderStatusStrategy.class);
        strategyMap.values().forEach(el -> orderStatusStrategyMap.put(el.getOrderStatusEnum(), el));
    

switchcase改成策略模式之后

可以看到代码清晰多了,扩展性也强了

vo.setOrderStatusDescription(orderStatusStrategyService.getOrderStatusDescription(orderInfoDO.getOrderStatus()));

以上是关于策略模式代替IfElse和SwitchCase的主要内容,如果未能解决你的问题,请参考以下文章

策略模式

Python设计模式-策略模式

设计模式-策略模式Strategy以及消灭if else

有效的减少代码中太多的ifelse?-策略模式

别在再满屏的 ifelse 了,试试策略模式,真香!!

别在再满屏的 ifelse 了,试试策略模式,真香!!