策略模式_高级使用

关于策略模式,本人博文其他有写,此文只描述最高级使用技巧,基于策略类加载及配置的策略的策略选择(后面比较不易理解,简单说就是配置使用策略的策略)。基于思考和工作实践,对于改写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;
    }

}

其他应用:可配置化场景

猜你喜欢

转载自blog.csdn.net/haohaounique/article/details/124568520