在策略模式的基础上使用模版模式

前两天使用了策略模式,但是发现还是不够,不够在哪呢?因为我不仅想让SpringBoot执行不同的策略,我还想对这个策略进行限制,让它按照我的想法执行策略,不能在策略接口的实现中胡作非为,那么该怎么办呢??引入模版模式加一个限制,每个具体的策略必须继承自这个抽象的策略就好了。

下面是具体实现:

1
2
3
public interface IStrategy {
DispatchResultVO handler(List<Case> caseList, List<UserInformationDto> userInformationList , int strategy);
}

首先定义一个抽象类用来对策略进行限制,并实现IStrategy接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class AbstractStrategy implements IStrategy{
// 抽象的方法是需要具体策略实现的
protected abstract void limitFilter();
protected abstract void target();
// 不抽象的方法是公共的
protected void km() {}
protected void dispatch() {}
// 实现 IStrategy 接口中的方法,从而执行不同的策略,这里使用final是禁止子类重写handler方法
@Override
public final DispatchResultVO handler(List<Case> caseList, List<UserInformationDto> userInformationList, int strategy){
limitFilter();
target();
km();
dispatch();
return null;
}
}

然后具体的策略就不需要实现IStrategy接口了,而是要继承AbstractStrategy抽象类:

1
2
3
4
5
6
7
8
9
10
11
12
@StrategyAnnotation(value = 4)
@Component
@Slf4j
public class TimeBest extends AbstractStrategy {
@Override
protected void limitFilter() {}

@Override
protected void target() {
log.info("TimeBest!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@StrategyAnnotation(value = 1)
@Component
@Slf4j
public class SkillBest extends AbstractStrategy {
public static int maxScore = 100;

@Override
protected void limitFilter() {}

@Override
protected void target() {
log.info("SkillBest!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
@StrategyAnnotation(value = 2)
@Component
@Slf4j
public class DistanceBest extends AbstractStrategy {
@Override
protected void limitFilter() {}

@Override
protected void target() {
log.info("DistanceBest!");
}
}

经过这样的限制,具体的策略实现类就只能按照抽象类中实现的handler方法中的定义来运行了。

具体在Service中使用策略就写成这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Service
public class DispatchAutoServiceImpl implements IDispatchAutoService {
@Resource
private StrategyContext strategyContext;

@Override
public void autoDispatch(String startTime, String endTime, int type) {
List<Case> caseList = new ArrayList<>();
List<UserInformationDto> userInformationList = new ArrayList<>();

IStrategy strategyHandler = strategyContext.getStrategy(type);
DispatchResultVO dispatchResultVO = strategyHandler.handler(caseList,userInformationList,type);
}
}