关于策略模式,本人博文其他有写,此文只描述最高级使用技巧,基于策略类加载及配置的策略的策略选择(后面比较不易理解,简单说就是配置使用策略的策略)。基于思考和工作实践,对于改写if else和其他配置化非常有用,此思想非常有用
使用:if else比较多,变更比较频繁场景
2.基于技术 redis +mysql+本地缓存+自定义工具类
演示案例无数据库加载,具体需依据业务处理来
一、基于策略的策略设计:1.key1+key2+key3+....keyN==key 2.从redis hashkey中获取对应的value值
3.基于对应的value值,再从另外一个hashkey中选择.....此处基于业务设计需要
比较适合1对1场景,即一个操作产生一种结果
选择 结果
001 002
002 003
004 005
基于hash结构+数据库配置(相信经常写代码的你能够看懂),用处比较多,个人认为,某些时候基于redis结构去做策略选择会比代码更好
如 手机区号, 深圳(SZ) 北京(BJ) hash存储,hash获取,这样减少了if else判断(多的话可以基于数据库配置化加载方式)
127.0.0.1:6379> hset check_phone SZ 001
127.0.0.1:6379> hset check_phone BJ 002
二、基于策略选择策略类
顶级业务校验处理类较为固定场景
基于redis hash结构,选择对应维度key的配置,再通过spring容器获取bean来处理具体业务
思路:通过维度key选取出具体的配置类名,然后通过类名从spring容器中来获取对应的类
如 redis hash 存储 SZ --- szPhoneCheck
获取到IPhoneCheck,从而来调用chekPhone方法
顶级类
public interface IPhoneCheck { boolean checkPhone(String key); }
实现类1 @Service public class szPhoneCheck implements IPhoneCheck{ @Override public boolean checkPhone(String key) { return false; } }
实现类2 @Service public class bjPhoneCheck implements IPhoneCheck{ @Override public boolean checkPhone(String key) { return false; } }
@Service
@Slf4j
public class OrderInfoService {
/**
* 本地缓存
* maven坐标
* <dependency>
* <groupId>com.github.ben-manes.caffeine</groupId>
* <artifactId>caffeine</artifactId>
* <version>3.0.6</version>
* </dependency>
*/
private static final Cache<String, IPhoneCheck> PHONE_CHECK = Caffeine.newBuilder().initialCapacity(10).expireAfterWrite(1, TimeUnit.DAYS).maximumSize(10000).build();
public boolean checkParam(String key, String phone) {
//key 还可以配置数据库,缓存方式获取
IPhoneCheck phoneCheck = PHONE_CHECK.getIfPresent(key);//优先从缓存中获取
if (phoneCheck == null) {
phoneCheck = SpringBeanUtils.getBeanByName(key, IPhoneCheck.class);
}
if (phoneCheck == null) {
return false;
}
try {
return phoneCheck.checkPhone(phone);
} catch (Exception e) {
return false;
}
}
}
springbean工具类
@Component
public class SpringBeanUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public Object getBean(String name) {
return context.getBean(name);
}
public <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
public static <T> T getBeanByName(String beanName, Class<T> clazz) {
return context.getBean(beanName, clazz);
}
public static ApplicationContext getApplicationContext() {
return context;
}
}
其他应用:可配置化场景