前一段时间写一篇策略模式结合spring使用,但是最近发现一点点小问题,就是上次的写法他不符合开闭原则。
开闭原则呢简单来说就是:一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来实现变化的(具体的大家可以自行百度)
我们原先的代码呢如下:
public class ActionHandlerFactory {
private static Map<Byte, ActionHandler> ROUT_MAP;
@Autowired
private TeacherActionHandler teacherActionHandler;
@Autowired
private UserActionHandler userActionHandler;
@PostConstruct
private void init(){
ROUT_MAP= ImmutableMap.<Byte,ActionHandler>builder()
.put(ActionEnum.USER.getType(),userActionHandler)
.put(ActionEnum.TEACHER.getType(),teacherActionHandler).build();
}
public Map<Byte,ActionHandler> getRoutMap(){
return ROUT_MAP;
}
}
可以看见我们每次增加一个新的处理逻辑都会对原先的代码进行修改,这样就是违背了开闭原则。唉!!!!!!!
知错能改善莫大焉,知道自己出了什么问题,我就改了一下自己的实现逻辑,新的代码如下
@Slf4j
@Component
public class ActionHandlerFactory implements BeanPostProcessor {
private Map<Byte, ActionHandler> ROUT_MAP=new HashMap<>();
// @Autowired
// private TeacherActionHandler teacherActionHandler;
// @Autowired
// private UserActionHandler userActionHandler;
// @PostConstruct
// private void init(){
// ROUT_MAP= ImmutableMap.<Byte,ActionHandler>builder()
// .put(ActionEnum.USER.getType(),userActionHandler)
// .put(ActionEnum.TEACHER.getType(),teacherActionHandler).build();
// }
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof ActionHandler){
Byte type = ((ActionHandler) bean).getType();
ROUT_MAP.put(type,(ActionHandler) bean);
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
public Map<Byte,ActionHandler> getRoutMap(){
return ROUT_MAP;
}
}
可以看见我让ActionHandlerFactory实现了BeanPostProcessor这个类,之后重写了postProcessAfterInitialization这个方法,这个方法就是在spring中bean初始化完毕之后,执行的方法,大家可以断点看一下,spring中管理的所有bean都会当做参数传进来。这样我们可以选择我们自己想要的bean完成我们自己的逻辑。
附上 TeacherActionHandler 代码增加了一个抽象方法的实现 getType
public class TeacherActionHandler extends ActionHandler{
@Override
public void insert(ActionVO actionVO) {
// 就是写 Ctrl+V
System.out.println("im teacher");
}
@Override
public Byte getType() {
return ActionEnum.TEACHER.getType();
}
@Override
public void write(ActionVO actionVO) {
super.write(actionVO);
//自己逻辑 就是 Ctrl+C
}
@Override
public void read(ActionVO actionVO) {
super.read(actionVO);
//自己的逻辑 卡卡就是干
}
}
上述就是我对我的策略模式使用的优化,如果这种方式有效率或者什么其他问题欢迎大家给我指正。