https://www.runoob.com/design-pattern/strategy-pattern.html
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
目前有个场景,小学和少儿有同一套答题流程,但是每个关键环节都是有各自的三方服务,如何根据学段来区分哪一套三方服务:
1.先创建context
AnswerServiceContext
两个方法,根据部门判断是少儿还是中学,来通过factory获取各自的bean
@Data
@Service
public class AnswerServiceContext {
/**
* 设置 AnswerService
* @param deptCode
*/
private AnswerService getAnswerService(String deptCode){
if(StringUtils.isEmpty(deptCode)){
throw new BusinessException(ErrorsEnum.ERROR_PARAM);
}
Integer type = "05".equals(deptCode)? QuestionBankEnum.POP.getCode():QuestionBankEnum.UCAN.getCode();
return AnswerServiceFactory.getInstance().creator(type);
}
/**
* 开始答题
* @param beginResultVO
* @return
*/
public ResponseEntity<TestBeginVO> answerBegin(ExamBeginResultVO beginResultVO){
AnswerService answerService = getAnswerService(beginResultVO.getDeptCode());
return answerService.answerBegin(beginResultVO);
}
/**
* 查看报告
* @param testId
* @param deptCode
* @return
*/
public ResponseEntity<ReportResultVO> getReportByTestId(String testId, String deptCode){
AnswerService answerService = getAnswerService(deptCode);
return answerService.getReportByTestId(testId);
}
}
2.创建factory
AnswerServiceFactory
package cn.xdf.ec.testing.service.biz.strategy;
import org.springframework.beans.BeansException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/**
* @program: k12-testing-api
* @description: 策略单利 饿汉式 简单实用
*/
@Service
@ConditionalOnBean(value = {PopAnswerService.class,UcanAnswerService.class})
public class AnswerServiceFactory implements ApplicationContextAware {
// 饿汉式单利
private static AnswerServiceFactory factory = new AnswerServiceFactory();
private AnswerServiceFactory(){
}
private static Map<Integer,AnswerService> serviceMap = new HashMap<>();
public AnswerService creator(Integer type){
return serviceMap.get(type);
}
public static AnswerServiceFactory getInstance(){
return factory;
}
/**
* 把bean放入工厂
**/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
serviceMap.put(1,applicationContext.getBean(PopAnswerService.class));
serviceMap.put(2,applicationContext.getBean(UcanAnswerService.class));
}
}
3.各自的接口实现
AnswerService 和 AnswerServiceImpl
public interface AnswerService {
/**
* 开始答题
* @param beginResultVO
* @return
*/
ResponseEntity<TestBeginVO> answerBegin(ExamBeginResultVO beginResultVO);
/**
* 获取测评报告
* @param testId
* @return
*/
ResponseEntity<ReportResultVO> getReportByTestId(String testId);
}
实际使用:
@Resource
private AnswerServiceContext answerServiceContext;
answerServiceContext.answerBegin(resultVO);