7. 设计模式——策略模式

158 阅读1分钟

直接上代码,现在业务中用的

首先定义一个注解,通过此注解来注册策略

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ActionType {
    String value();
}

定义action,业务通过此type来获取不同的策略

public class ActionTypeConstant {
    public static final String ACTION_TYPE_TEST = "test";
    public static List<String> actionTypes = new ArrayList<>();

    static {
        actionTypes.add(ACTION_TYPE_TEST);
    }

    public static boolean checkInActions(String actionType) {
        return actionTypes.contains(actionType);
    }
}

策略接口

public interface IStrategy {
    boolean action(Object obj);
}

定义一个帮助类,用来注册策略

@Component
class StrategyService {
    @Autowired
    private List<IStrategy> strategies;

    private static Map<String, IStrategy> STRATEGIES_MAP = new HashMap();

    @PostConstruct
    private void init () {
        if (CollectionUtils.isEmpty(strategies)) {
            return;
        }

        for (IStrategy strategy : strategies) {
            String key = null;
            key = strategy.getClass().getAnnotation(ActionType.class).value();
            if (!StringUtils.isEmpty(key)) {
                STRATEGIES_MAP.put(key, strategy);
            }
        }
    }

    public IStrategy getStrategy (String actionType){
        Preconditions.checkArgument(PoolActionTypeConstant.checkInActions(actionType), "action type error");
        return STRATEGIES_MAP.get(actionType);
    }
}

注册策略也可以用另一种方法

// 定义一个容器保存策略
@Component
public class StrategyContainer {

    public static Map<String, IStrategy> strategyContainer = new ConcurrentHashMap<>();

    public static void register(String actionType, IStrategy strategy) {
        Assert.notNull(actionType, "action type can`t be null");
        Assert.notNull(strategy, "strategy can`t be null");

        strategyContainer.put(actionType, strategy);
    }

    public static IStrategy getStrategy(String actionType) {
        Assert.notNull(actionType, "action type can`t be null");

        return strategyContainer.get(actionType);
    }
}

// 每个策略中注册自己
@Slf4j
@Service
@ActionType("test")
class TestStrategy implements IStrategy, InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        StrategyContainer.register(this.getClass().getAnnotation(ActionType.class).value(), this);
    }
}

业务使用策略

strategyService.getStrategy(ActionTypeConstant.ACTION_TYPE_TEST).action(object);