策略模式的demo
策略一:ALI_PAY(“1”,“com.fjw.model2.AliPay”),加载类的实例调用
场景:不同code,获取支付类支付方式不同
创建公共的策略枚举类
PayEnumStrategy:
public enum PayEnumStrategy {
ALI_PAY("1","com.fjw.model2.AliPay"),
WX_PAY("2","com.fjw.model2.WxPay");
private String code;
private String className;
PayEnumStrategy() {
}
PayEnumStrategy(String code, String className) {
this.code = code;
this.className = className;
}
public static String getClassByCode(String code){
String className = "";
if (StringUtils.isEmpty(code)) {
System.out.println("code错误");
return className;
}
//遍历所有的可选策略值,找到对应的类
for (PayEnumStrategy payEnumStrategy : PayEnumStrategy.values()) {
if (payEnumStrategy.code.equalsIgnoreCase(code)){
className = payEnumStrategy.className;
break;
}
}
return className;
}
//不需要setter
public String getCode() {
return code;
}
public String getClassName() {
return className;
}
}
创建共有的行为
public interface PayStrategy {
String pay();
}
创建策略可以执行的方式
public class AliPay implements PayStrategy {
@Override
public String pay() {
System.out.println("ali支付");
return "支付包支付";
}
}
public class WxPay implements PayStrategy {
@Override
public String pay() {
System.out.println("微信支付");
return "微信支付";
}
}
根据编码获取执行方式策略实例
public class StrategyFactory {
public static PayStrategy getPayStrategyByCode(String code){
try {
return (PayStrategy) Class.forName(PayEnumStrategy.getClassByCode(code)).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
业务的调用执行
public class PayContextStrategy {
public static String toPay(String code){
if (StringUtils.isEmpty(code)){
return "code不能为空";
}
PayStrategy strategy = StrategyFactory.getPayStrategyByCode(code);
return strategy.pay();
}
public static void main(String[] args) {
PayStrategy strategy = StrategyFactory.getPayStrategyByCode("1");
strategy.pay();
}
}
策略二:实现接口的,以map<方式,要执行的方法>交给spring管理
场景:根据不同类型采取不同的解析方式
策略模式的使用:
- 一个接口或者抽象类,里面两个方法(一个方法匹配类型,一个可替换的逻辑实现方法)
- 不同策略的差异化实现(就是说,不同策略的实现类)
- 使用策略模式
一个接口,两个方法
public interface IFileStrategy {
//属于哪种文件解析类型
FileTypeResolveEnum gainFileType();
//封装的公用算法(具体的解析方法)
void resolve(Object objectparam);
}
不同策略的差异化实现
//A类型策略具体实现
@Component
public class AFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_A_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
logger.info("A 类型解析文件,参数:{}",objectparam);
//A类型解析具体逻辑
}
}
@Component //B
public class BFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_B_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
logger.info("B 类型解析文件,参数:{}",objectparam);
//B类型解析具体逻辑
}
}
@Component //默认
public class DefaultFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_DEFAULT_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
logger.info("默认类型解析文件,参数:{}",objectparam);
//默认类型解析具体逻辑
}
}
使用策略模式
借助spring
的生命周期,使用ApplicationContextAware
接口,把用的策略,初始化到map
里面。然后对外提供resolveFile
方法即可。map<枚举类,执行方法>
@Component
public class StrategyUseService implements ApplicationContextAware{
private Map<FileTypeResolveEnum, IFileStrategy> iFileStrategyMap = new ConcurrentHashMap<>();
public void resolveFile(FileTypeResolveEnum fileTypeResolveEnum, Object objectParam) {
IFileStrategy iFileStrategy = iFileStrategyMap.get(fileTypeResolveEnum);
if (iFileStrategy != null) {
iFileStrategy.resolve(objectParam);
}
}
//把不同策略放到map
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IFileStrategy> tmepMap = applicationContext.getBeansOfType(IFileStrategy.class);
tmepMap.values().forEach(strategyService -> iFileStrategyMap.put(strategyService.gainFileType(), strategyService));
}
}