策略模式
先看概念🙌
官方定义:策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在策略模式中,我们定义了一组算法,并且允许客户端应用程序在运行时选择要使用的实际算法。
说人话:挺好理解的,就是就是使用不同的策略算法不会影响到客户端的使用
适用场景😶🌫️
策略模式还是比较简单并且使用较多的,平常我们多运用策略模式用来消除 if-else、switch 等多重判断的代码,消除 if-else、switch 多重判断 可以有效应对代码的复杂性。
直接上demo
假设有一个根据不同商品类型计算折扣的问题。在没有使用策略模式的情况下,你可能会写出类似下面的代码:
public class DiscountCalculator {
public double calculateDiscount(String productType, double amount) {
if ("electronics".equals(productType)) {
return amount * 0.1;
} else if ("clothing".equals(productType)) {
return amount * 0.2;
} else if ("books".equals(productType)) {
return amount * 0.15;
} else {
return 0;
}
}
public static void main(String[] args) {
DiscountCalculator calculator = new DiscountCalculator();
double discount = calculator.calculateDiscount("electronics", 100);
System.out.println("Discount: " + discount);
}
}
我想将上述代码块改造为策略设计模式,怎么办?
别急🙌🙌🙌
先进行一层抽象!!!
把策略定义为一个抽象接口,然后写它的几个实现类,,最后写一个策略类来存储那几个实现类,对客户端屏蔽具体的创建细节
接下来,就是使用了,看看客户端怎么使用?
很简单,直接从策略工厂中选一个,然后执行具体的策略
没了?😂确实没了,话说各种设计模式只是一种思想,理解了最重要的是怎么想着在代码中使用到👌
公司中的实践
策略类的设计
首先定义策略类接口:
/**
* 商机库权限校验策略类
*/
public interface BusinessAuthStrategy extends InitializingBean
继承Spring中的InitializingBean是为了在重写afterPropertiesSet
重写是为了在Spring容器完成对当前bean的属性注入后,将这个bean注册到BusinessAuthFactory的策略工厂中
然后定义抽象策略类:
/**
* 商机库权限校验策略类
*/
public abstract class BusinessAbstractAuthStrategy implements BusinessAuthStrategy
然后其中一个具体策略实现:
/**
* 商机库地区&业态权限校验
*/
@Slf4j
@Service
@Component("businessAreaAuthStrategy")
public class BusinessAreaAuthStrategy extends BusinessAbstractAuthStrategy
策略工厂的设计
策略工厂中使用ConcurrentHashMap来保存每个策略
/**
* 商机库权限校验策略类工厂
*
* @author sjz
*/
@Slf4j
public class BusinessAuthFactory {
static Map<BusinessAuthEnum, BusinessAuthStrategy> businessLibraryQuotaStrategyHashMap = new ConcurrentHashMap<>();
private BusinessAuthFactory() {
}
public static void registryInstance(BusinessAuthEnum key, BusinessAuthStrategy service) {
if (!businessLibraryQuotaStrategyHashMap.containsKey(key)) {
businessLibraryQuotaStrategyHashMap.put(key, service);
}
}
public static BusinessAuthStrategy getInstance(BusinessAuthEnum key) {
return businessLibraryQuotaStrategyHashMap.get(key);
}
}
使用
直接使用策略工厂的静态方法完成校验
BusinessAuthFactory.getInstance(BusinessAuthEnum.CUSTOM_MONITORING
OK再见!周末快乐!