1. 策略+工廠實現相同業務抽象
策略模式:一種解耦的方法,它對演算法進行封裝,使得演算法的呼叫和演算法本身分離。使用策略模式客戶端程式碼不需要調整,演算法之間可以互相替換,因為不同的演算法實現的是同一個介面。策略模式是一種物件行為型模式。策略模式符合“開閉原則”。
1.1 定義策略介面
將成員的業務方法抽象為統一的策略介面。其中 InitializingBean 介面來自Spring框架,用於實現環境的統一工廠。
public interface SubjectTypeHandler {
/**
* 列舉身份的識別
*/
SubjectInfoTypeEnum getHandlerType();
/**
* 實際的題目的插入
*/
void add(SubjectInfoBO subjectInfoBO);
/**
* 實際的題目的查詢
*/
SubjectOptionBO query(int subjectId);
}
1.2 實現策略工廠
此處的工廠即策略模式下的 “環境類” 要素,功能為根據不同的name找到其對應的不同的策略實現,實現方法為將實現NameHandler介面的類都裝載到strategyMap裡,除使用工廠實現外,也可以使用列舉+代理實現。
@Component
public class SubjectTypeHandlerFactory implements InitializingBean {
@Resource
private List<SubjectTypeHandler> subjectTypeHandlerList;
private Map<SubjectInfoTypeEnum, SubjectTypeHandler> handlerMap = new HashMap<>();
public SubjectTypeHandler getHandler(int subjectType){
SubjectInfoTypeEnum byCode = SubjectInfoTypeEnum.getByCode(subjectType);
return handlerMap.get(byCode);
}
@Override
public void afterPropertiesSet() throws Exception {
for (SubjectTypeHandler subjectTypeHandler : subjectTypeHandlerList) {
handlerMap.put(subjectTypeHandler.getHandlerType(), subjectTypeHandler);
}
}
}
1.3 為各成員實現各自的具體策略實現類
將各自的不同實現類宣告為元件(用於維護工廠),org.springframework.beans.factory.InitializingBean#afterPropertiesSet內部實現工廠註冊。
/**
* 單選題目的策略類
*
*/
@Component
public class RadioTypeHandler implements SubjectTypeHandler {
@Resource
private SubjectRadioService subjectRadioService;
@Override
public SubjectInfoTypeEnum getHandlerType() {
return SubjectInfoTypeEnum.RADIO;
}
@Override
public void add(SubjectInfoBO subjectInfoBO) {
//單選題目的插入
List<SubjectRadio> subjectRadioList = new LinkedList<>();
subjectInfoBO.getOptionList().forEach(option -> {
SubjectRadio subjectRadio = RadioSubjectConverter.INSTANCE.convertBoToEntity(option);
subjectRadio.setSubjectId(subjectInfoBO.getId());
subjectRadio.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
subjectRadioList.add(subjectRadio);
});
subjectRadioService.batchInsert(subjectRadioList);
}
@Override
public SubjectOptionBO query(int subjectId) {
SubjectRadio subjectRadio = new SubjectRadio();
subjectRadio.setSubjectId(Long.valueOf(subjectId));
List<SubjectRadio> result = subjectRadioService.queryByCondition(subjectRadio);
List<SubjectAnswerBO> subjectAnswerBOList = RadioSubjectConverter.INSTANCE.convertEntityToBoList(result);
SubjectOptionBO subjectOptionBO = new SubjectOptionBO();
subjectOptionBO.setOptionList(subjectAnswerBOList);
return subjectOptionBO;
}
}
public class MultipleTypeHandler implements SubjectTypeHandler
......
經過改造,後面如果新增成員或者新功能實現,新增策略實現即可。這種改造符合開閉原則,適用較為複雜的邏輯判斷。