一、策略模式的结构
在java中,策略模式通常包含以下三个组件:
· 环境类(Context):用来维护以一个策略的引用。
· 策略接口(Strategy):所有策略类都必须实现的接口。
· 策略实现类(ConcreteStrategy):实现策略接口的具体算法。
二、优缺点
优点:
· 方便扩展,当我们需要增加一个策略时,只需要添加相应的策略实现就好了。
· 职责单一,不同策略的具体实现都是独立的。
缺点:
· 每一个策略都要对应一个java文件,当需要大量策略时会导致文件数量膨胀。
三、实战
现在需要为运营商三家生成供他们填写的excel,excel的内容由于三家运营商而不同,需要定制化。
项目架构:
java.com.xxx.xxx:
-- controller
ExcelController
-- entity
-- service
-- Impl
ExcelServiceImpl
ExcelService
-- strategy
-- Impl
CTCCExcel
CMCCExcel
CUCCExcel
CreateExcelStrategy
CreateContext
CreateExcelStrategy
public interface CreateExcelStrategy {
Workbook createWorkBook(String reportId) throws BizException;
}
CreateContext:
@Component
public class CreateContext {
private final Map<String, CreateExcelStrategy> strategyMap = new ConcurrentHashMap<>();
@Autowired
public CreateContext (Map<String, CreateExcelStrategy> strategyMap) {
this.strategyMap.clear();
strategyMap.forEach(this.strategyMap::put);
}
/**
* 生成不同的excel
* @return
*/
public Workbook createWorkBook(String type,String reportId) throws BizException{
CreateExcelStrategy strategy = strategyMap.get(type);
if(strategy!=null) {
return strategy.createWorkBook(reportId);
}
throw new BizException(ERROR.TYPR);
}
}
具体的策略实现:
//CMCCExcel
@Service("CMCC")
public class CreateCMCC implements CreateExcelStrategy {
private static final Logger logger = LoggerFactory.getLogger(CreateCMCC.class);
@Override
public Workbook createWorkBook(String reportId) throws BizException {
//具体生成excel逻辑
... ...
}
}
//CTCCExcel
@Service("CTCC")
public class CreateCTCC implements CreateExcelStrategy {
private static final Logger logger = LoggerFactory.getLogger(CreateCTCC.class);
@Override
public Workbook createWorkBook(String reportId) throws BizException {
//具体生成excel逻辑
... ...
}
}
//CUCCExcel
@Service("CUCC")
public class CreateCUCC implements CreateExcelStrategy {
private static final Logger logger = LoggerFactory.getLogger(CreateCUCC.class);
@Override
public Workbook createWorkBook(String reportId) throws BizException {
//具体生成excel逻辑
... ...
}
}
ExcelController层代码:
@PostMapping("/export")
public R importExcel(@RequestParam("param1") String param1,
HttpServletRequest request,
HttpServletResponse response) {
try {
logger.info("/excel/export接口导出的param1={}", param1);
excelService.exportExcel(reportId, response);
} catch (BizException e) {
return R.error(e.getBizCode(), e.getBizMessage());
}
return R.ok();
}
Service层代码:
@Service
public class ExcelServiceImpl implements ExcelService {
private static final Logger logger = LoggerFactory.getLogger(ExcelServiceImpl.class);
@Autowired
private CreateContext context;
@Override
public void exportExcel(String reportId, HttpServletResponse response) throws BizException {
try {
//生成三个excel文件
Workbook CTCCBook=context.createWorkBook(Contants.CTCC,reportId);
Workbook CMCCBook=context.createWorkBook(Contants.CMCC,reportId);
Workbook CUCCBook=context.createWorkBook(Contants.CUCC,reportId);
//其他逻辑
... ...
}catch(BizException e){
throw e;
}
}
已上就是java之策略模式的使用。
最后要说明,策略模式的三大组件,其中有一个可以略写,使代码可阅读性更高。在本篇就不说了。