策略者模式
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
实现
我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。
StrategyPatternDemo,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。
业务场景
现在有一个退改签机票的场景:
机票有这么几个属性:
退改类型:自愿(Will),非自愿(Unwill)
操作类型:refund(退票),change(改签)
所以一共会出现四种组合形式,每种处理流程对应策略者中的一个处理器。
处理结构如下图:
ISupport: 定义了一个support方法,表示该执行器支不支持当前机票类型的处理。
public interface ISupport<T> {
/**
* 是否支持方法
* @param t
* @return
*/
boolean support(T t);
}
IProcess:所有执行器必须实现的接口类,定义了处理机票的核心方法process
public interface IProcess extends ISupport<QmqSupportRequest> {
/**
* 核心处理方法
*/
void process(Object obj);
}
CommonMethodService:公共方法类,封装了每个机票处理器可能用到的公共方法
WillChangeProcess;UnwillChangeProcess,WillRefundProcess,WillChangeProces四个类为具体的执行器:
public class WillChangeProcess extends CommonMethodService implements IProcess
处理器中@Override 了process核心处理方法,support该处理器支持的处理类型。
选择执行器
package com.qunar.flight.domestic.autotgq.master.service;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class SpringService {
@Autowired
private ApplicationContext applicationContext;
//getBeanList的实现
public static <T> List<T> getBeanList(Class<T> clazz) {
// getBeanNamesForType 获取容器中指定某类型、或实现某接口、或继承某父类所有的 Bean 的名称
String[] names = applicationContext.getBeanNamesForType(clazz);
if (names == null || names.length == 0) {
return null;
}
List<T> beans = Lists.newArrayList();
for (String name : names) {
//获取指定名字的 Bean
beans.add(applicationContext.getBean(name, clazz));
}
return beans;
}
}
//获取到所有的实现类--所有implement实现了IProcess接口的类
List<IProcess> iProcessList = SpringService.getBeanList(IProcess.class);
for (IProcess executor : iProcessList) {
//support方法来判断执行器是否符合要求
if (executor.support(request)) {
log.info("found executor...");
return executor;
}
}
//invoker找到对应的executor执行器后,执行执行器的process方法处理具体流程。
if (Objects.nonNull(executor)) {
executor.process(request);
}