策略模式与map和枚举结合实现动态调用实现类

策略模式与map和枚举结合实现动态调用实现类

问题来源:开发的时候,有一个接口需要根据参数的值来调用相应的方法去实现,每个方法实现的逻辑有点不一样,传统方法是用一堆if去判断调用哪个方法,显得代码不好看,通过学习策略模式解决了该问题。

实现步骤:

第一步:需要抽取出一个接口,里面放抽取出来的方法

public interface IHikResultProcessStrategy {

    /**
     * 解析字符串
     * @param str
     */
    void resultProcess(String str);
}

第二步:定义具体实现类,这里我有两个实现类,具体实现根据业务需求,我这里用打印简单代替

一:

@Service
@Slf4j
public class HikAreaIntrudeResultProcessStrategy implements IHikResultProcessStrategy {
    @Override
    public void resultProcess(String str) {
        log.info("HikAreaIntrudeResultProcessStrategy");
    }
}

二:

@Service
@Slf4j
public class HikFireDetectionResultProcessStrategy implements IHikResultProcessStrategy {
    @Override
    public void resultProcess(String str) {
        log.info("HikFireDetectionResultProcessStrategy");
    }
}

第三步:需要定义一个context类将这些实现类添加到map里面

@Component
public class HikResultProcessContext {

    private final Map<String, IHikResultProcessStrategy> resultProcessStrategy;
    //将实现类放在枚举里面,遍历添加到map
    public HikResultProcessContext() {
        resultProcessStrategy = new HashMap<>();
        for (HikResultProcessStrategyEnum strategy : HikResultProcessStrategyEnum.values()) {
            resultProcessStrategy.put(strategy.getKey(), strategy.getStrategy());
        }
    }
	//需要的时候通过key去取实现类
    public void getResultProcessStrategy(String strategyKey, String str) {
        IHikResultProcessStrategy strategy = resultProcessStrategy.get(strategyKey);
        if (strategy == null) {
            throw new IllegalArgumentException("Invalid strategy key: " + strategyKey);
        }
        strategy.resultProcess(str);
    }
}

枚举类如下:

@Getter
@AllArgsConstructor
public enum HikResultProcessStrategyEnum {
    AREA_INTRUDE(1000,"areaIntrude", new HikAreaIntrudeResultProcessStrategy()),
    FIRE_DETECTION(2000,"fireDetection", new HikFireDetectionResultProcessStrategy());

    private final Integer code;
    private final String key;
    private final IHikResultProcessStrategy strategy;
}

第四步:调用

@Service
@Slf4j
public class HikEventSubServiceImpl implements IHikEventSubService {
    @Autowired
    private HikResultProcessContext resultProcessContext;
    
    @Override
    public void push(String bodyStr) {
        Integer eventType = 1000;
        log.info("eventType===>{}", eventType);
        //遍历枚举去找对应的实现类实现
        for (HikResultProcessStrategyEnum strategy : HikResultProcessStrategyEnum.values()) {
            if (strategy.getCode().equals(eventType)){
                resultProcessContext.getResultProcessStrategy(strategy.getKey(), bodyStr);
            }
        }

    }
}

第五步:结果

2023-11-10 15:39:54.209  INFO 15856 --- [http-nio-58180-exec-2] .i.i.HikAreaIntrudeResultProcessStrategy 19 : HikAreaIntrudeResultProcessStrategy

可能会发生的问题解决:

问题:我在使用上面方法的时候想在具体的策略类接口想要利用@Autowired去注入其他类,却发现注入不进去,报空指针问题

原因:因为我在枚举类里面的策列类是通过new出来的方式,所以无法依赖spring自动注入注入其他类

解决:

第一步:引入工具类

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy(false)
public class SpringUtil implements ApplicationContextAware  {
	private static ApplicationContext applicationContext = null;
	public static ApplicationContext getApplicationContext(){return applicationContext;}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		// TODO Auto-generated method stub
		if(SpringUtil.applicationContext == null){
			SpringUtil.applicationContext = applicationContext;
		}
	}
	
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
 
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

第二步:改变枚举类,bean的方式通过工具类去获取

@Getter
@AllArgsConstructor
public enum HikResultProcessStrategyEnum {
    AREA_INTRUDE("131588","areaIntrude", SpringUtil.getApplicationContext().getBean(HikAreaIntrudeResultProcessStrategy.class)),
    FIRE_DETECTION("fireDetection","fireDetection", SpringUtil.getApplicationContext().getBean(HikFireDetectionResultProcessStrategy.class)),
    SMOKE_DETECTION("smokeDetection", "smokeDetection", SpringUtil.getApplicationContext().getBean(HikSmokeDetectionResultProcessStrategy.class));
    private final String code;
    private final String key;
    private final IHikResultProcessStrategy strategy;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值