策略模式简单实用java

一个超级简单且实用的策略模式。
首先,定义一个抽象的策略处理器

/**
 * @author pikadog~
 * 抽象处理类
 */
public abstract class AbstractSolver  {
    /**
     *一个处理器可以处理多个类型,用来指定什么情况下会选择当前策略
     * @return
     */
    public abstract SolverType[] solverTypes();

    /**
     * 业务逻辑
     * @param param
     * @return
     */
    public Object doSolver(Object param) {
        return param;
    }
}

策略类型

/**
 * @author pikadog~
 * 2022/2/28 15:46
 */
public enum  SolverType {
    ONE( "solver1"),
    TWO( "solver1");
    private String type;

    SolverType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

然后就是用来管理策略的选择器

/**
 * @author pikadog~
 * 策略处理器的选择器,用来管理处理器
 * 相当于一个容器,hashMap
 * @date 2022/1/7 11:07
 */
@Component
public class SolverChooser implements ApplicationContextAware {
    private final static Map<SolverType, AbstractSolver> CHOOSER_SOLVERS_MAP = new HashMap<>();
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @PostConstruct
    public void register() {
        /**
         * 把所有容器中的处理器收集起来放到map里集中管理
         */
        Map<String, AbstractSolver> solverMap = applicationContext.getBeansOfType(AbstractSolver.class);
        for (AbstractSolver solver : solverMap.values()) {
            for (SolverType type : solver.solverTypes()) {
                CHOOSER_SOLVERS_MAP.put(type,solver);
            }
        }
    }

    /**
     * 根据类型选择策略
     * @param type
     * @return
     */
    public AbstractSolver choose(SolverType type) {
        return CHOOSER_SOLVERS_MAP.get(type);
    }
}

这里的@PostConstruct也可以换成其他的初始化方法,注意他们的执行顺序,以实现不同的业务需求。
例如@PostConstruct >早于afterPropertiesSet() 早于 initMethod()执行。

具体的处理器

@Component
public class TwoSolver extends AbstractSolver {
    @Override
    public SolverType[] solverTypes() {
        return new SolverType[]{SolverType.ONE,SolverType.TWO};
    }

    /**
     * 实际执行的业务方法
     * @param param
     * @return
     */
    @Override
    public Object doSolver(Object param) {
        System.out.println("one,two");
        return super.doSolver(param);
    }
}


    @Test
    void contextLoads() {
        Object o = chooser.choose(SolverType.ONE).doSolver(new TUser());
        Object o2 = chooser.choose(SolverType.TWO).doSolver(new TUser());
    }
//此时都会输出one,two

也可以把选择器和抽象处理器放一起

public abstract class SolverChooserAndDo {


    private final static Map<String, SolverChooserAndDo> HASH_MAP = new HashMap<>();

    public static SolverChooserAndDo getServiceType(String serviceType) {
        return HASH_MAP.get(serviceType);
    }

    /**
     * 策略的key,用来将服务类注册进HASH_MAP
     *
     * @return String
     */
    public abstract String serviceType();

    @PostConstruct
    public void init() {
        put(this.serviceType(), this);
    }

    private void put(String serviceKey, SolverChooserAndDo service) {
        HASH_MAP.put(serviceKey, service);
    }

    /**
     * 具体逻辑
     * @param param
     */
    public abstract void sendAward(Object param);

    /**
     * 多个具体业务逻辑
     * @param param
     */
    public abstract void check(Object param);
}

用法和逻辑都是一样的 这样写比较简单。

可以考虑把抽象处理器和选择器的参数换成泛型,这样每个业务逻辑就不用再写一套选择器和抽象处理器了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LxyrichBos

老板~坐下喝杯茶啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值