策略模式-自动和手动模式的不同实现
策略接口
用于提供策略入口
public interface ApplyStrategy{
void doDeal();
}
策略实现类
// 实现类-通过申请
@Component("PassStrategyImpl")
public class PassStrategyImpl implements ApplyStrategy{
@Override
public void doDeal(){}
}
// 实现类-拒绝申请
@Component("RefuseStratgyImpl")
public class RefuseStratgyImpl implements ApplyStrategy{
@Override
public void doDeal(){}
}
策略使用
方式有多种,按需使用,以下为业务代码省略DealService
及部分细节
直接使用
最简单的,直接根据业务去创建对应的实例
@Service
public class DealServiceImpl implements DealService{
ApplyStrategy passStrategy = new PassStrategyImpl();
passStrategy.doDeal();
ApplyStrategy refuseStrategy = new RefuseStratgyImpl();
refuseStrategy.doDeal();
}
枚举类
这种方式主要依靠@Resource
注解将容器内匹配到的Bean注入到Map中,然后通过枚举类确定所需Bean的名称
public enum ApplyStrategyEnum{
PASS(1,"PassStrategyImpl"),
REFUSE(2,"RefuseStratgyImpl");
@Getter
private int code;
@Getter
private String serviceName;
ApplyStrategyEnum(int code,String serviceName){
this.code = code;
this.serviceName = serviceName;
}
public static String getServiceNameByCode(int code){
for(ApplyStrategyEnum item : ApplyStrategyEnum.values()){
if(item.getCode() == code){
return item.getServiceName();
}
}
}
}
使用时,此方式可以通过前端传入ApplyStrategyEnum
实现自动选择策略类
@Service
public class DealServiceImpl implements DealService{
// 这里是重点
@Resource
private Map<String,ApplyStrategy> map;
ApplyStrategy applyStrategy = map.get(ApplyStrategyEnum.getServiceNameByCode(dto.getApplyStrategyEnum().getCode()));
applyStrategy.doDeal();
}
上述方式中,可以从Map中直接获取到对应的策略实现类实例的原理
使用@Resource 注解时,Spring能够自动将容器中所有符合条件的Bean注入到指定的集合中。针对上述用法具体来说,Spring会执行以下操作:
1.类型匹配:Spring会查找类型为ApplyStrategy的Bean
2.名称作为键:对于每个匹配的Bean,Spring会使用其Bean名称作为Map的Key。Bean名称通常是类名的首字母小写,除非你使用了其他方式定义Bean名称(例如,使用@Component("PassStrategyImpl"))
3.实例作为值:该Bean的实例将作为Map的value
其他
可能有的写法会出于安全考虑?会仅通过枚举类或者前端的一个参数,然后自行通过方法去创建实例,这种相当于是优化了上述直接使用的方法,不过多写了
public ApplyStrategy getApplyStrategy(int code){
if(code == 1){
return new PassStrategyImpl();
}
if(code == 2){
return new RefuseStratgyImpl();
}
else{
return null;
}
}
最后,策略模式本身就是为了方便,按需使用就好,同时可以学到@Resource
注解和Map结合使用的效果