设计模式之Spring整合策略设计模式

592 阅读2分钟

前言

  • 上篇文章介绍了策略模式的基本原理和实现机制 策略设计模式详解,但是我们在具体调用某一个策略时都是用new的方式来获取策略类实例。那这一点就spring的控制反转和依赖注入就设计思想就不符合。
  • 那如何让spring容器机制管理具体的策略类,下面就一起看看吧。

具体项目中代码示例

  • 在实际项目中可以把策略模式和spring整合在一起。
/**
 * 策略顶级接口
 *
 * @Author: ZRH
 * @Date: 2020/12/23 12:00
 */
public interface AbstractAppPage<T> {

    /**
     * 策略实现的抽象方法
     *
     * @param t
     */
    void insertOrUpdate(T t);
}
/**
 * 策略实现类,并自定义Bean名
 *
 * @author: ZRH
 * @vesion: 1.2.0
 * @time: 2020/12/23 19:06
 */
@Slf4j
@Service(AppPageRecord.FISH_CARD_PAGE)
public class CountFishCardBuriedPointServiceImpl implements AbstractAppPage<AppPageRecord> {

    @Override
    public void insertOrUpdate(AppPageRecord record) {
        // TODO
    }
}
/**
 * 策略控制类处理器
 *
 * @Author: ZRH
 * @Date: 2020/12/23 13:41
 */
@Component
public class AppPageContextHandler {

    /**
     * 存放抽象类集合
     */
    private final static Map<String, AbstractAppPage> MAP = Maps.newConcurrentMap();

    /**
     * 使用@Autowired注解在构造方法上,spring会自动扫描符合的Bean到map容器中,key为bean名称,value为bean实例
     *
     * @param map
     */
    @Autowired
    public AppPageContextHandler(Map<String, AbstractAppPage> map) {
        MAP.clear();
        MAP.putAll(map);
    }

    /**
     * 根据自定义条件找到bean并执行策略
     */
    public void buildInsertOrUpdate(AppPageRecord record) {
        if (null == record || StringUtils.isEmpty(record.getAppPageType())) {
            return;
        }
        MAP.get(record.getAppPageType()).insertOrUpdate(record);
    }
}
/**
 * 配置的bean名称实体类
 *
 * @Author: ZRH
 * @Date: 2020/12/23 10:21
 */
@Data
public class AppPageRecord {

    /**
     * CountFishCardBuriedPointServiceImpl - beanName
     */
    public static final String FISH_CARD_PAGE = "fish_card_page";

    /**
     * 埋点类型
     */
    private String appPageType;

    // other
}
/**
 * 模拟业务调用策略类
 *
 * @author: zrh
 * @vesion: 1.2.0
 * @time: 2020/12/23
 */
@Slf4j
@Configuration
public class AppPageConsumer implements InitializingBean {

    @Autowired
    private AppPageContextHandler appPageContextHandler;

    public void doConsume(String message) {
        try {
            AppPageRecord record = JSONObject.parseObject(message, AppPageRecord.class);
            // 模拟添加beanName
            record.setAppPageType(AppPageRecord.FISH_CARD_PAGE);
            // 保存或修改记录
            appPageContextHandler.buildInsertOrUpdate(record);
        } catch (Exception e) {
        }
    }

    @Override
    public void afterPropertiesSet() {
        try {
            // doSomeThing
        } catch (Exception e) {
        }
    }
}
  • 关于中间的AppPageContextHandler策略控制类处理器类其实是可以省略,在AppPageConsumer模拟业务调用策略类中直接使用下面这种方式也是可以的。具体操作就等读者自己思考。
@Autowired
private Map<String, AbstractAppPage> beanMap;

最后

  • 虚心学习,共同进步 -_-