简介
策略模式:定义了一系列的算法族,每一个算法都实现了接口的需要处理的方法,算法族可以互换。Context类是使用算法族的类,其中的方法会调用算法族中方法。我可以通过一个参数的不同值去动态改变需要调用的算法。
example
我们根据不同的类型去调用不同的事件处理器,相当于一个事件分发器
定义算法族
接口:Eventhandle,所有算法都需要实现这个接口,然后具体的逻辑在这里实现
public interface EventHandle {
public void handle(String param);
}
定义算法之前,我们还需要一个类型枚举,因为是根据类型去动态调用不同地算法
public enum Type {
CREATE, START, HANDLE ,END, OTHER;
}
此外,还需要一个注解,用来映射类型和算法族
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Event {
Type value();
}
接下来定义各个算法
@Component
@Event(Type.START)
public class StartEventHandle implements EventHandle {
@Override
public void handle(String param) {
System.out.println("StartEventHandle...");
}
}
@Component
@Event(Type.CREATE)
public class CreateEventHandle implements EventHandle {
@Override
public void handle(String param) {
System.out.println("CreateEventHandle...");
}
}
@Component
@Event(Type.HANDLE)
public class HandleEventHandle implements EventHandle {
@Override
public void handle(String param) {
System.out.println("HandleEventHandle...");
}
}
@Component
@Event(Type.END)
public class EndEventHandle implements EventHandle {
@Override
public void handle(String param) {
System.out.println("EndEventHandle...");
}
}
@Component
@Event(Type.OTHER)
public class OtherEventHandle implements EventHandle {
@Override
public void handle(String param) {
System.out.println("OtherEventHandle...");
}
}
至此,我们已经定义好了算法族
定义调用算法的类Context
首先,我们可以将所有的算法注入到这个类,我们使用map保存,但普通的注入是,bean的名字作为key, 但我们需要的是类型和算法的映射,所以我们使用构造函数注入,通过算法类的注解稍微做一些处理。
private final Map eventHandleMap = new ConcurrentHashMap<>();
@Autowired
public EventContext(Map eventContextMap) {
this.eventHandleMap.clear();
eventContextMap.forEach((key, value) -> {
Event annotation = AnnotationUtils.findAnnotation(value.getClass(), Event.class);
this.eventHandleMap.put(annotation.value(), value);
});
}
这样很巧妙的转换了bean的映射关系,类型到算法的映射
最后,需要定义处理函数去调用算法实现的方法
public void handle(Type type, String param) {
EventHandle eventHandle = eventHandleMap.get(type);
eventHandle.handle(param);
}
这样就动态实现了不同的类型调用不同的算法
EventContext
@Component
public class EventContext {
private final Map eventHandleMap = new ConcurrentHashMap<>();
@Autowired
public EventContext(Map eventContextMap) {
this.eventHandleMap.clear();
eventContextMap.forEach((key, value) -> {
Event annotation = AnnotationUtils.findAnnotation(value.getClass(), Event.class);
this.eventHandleMap.put(annotation.value(), value);
});
}
public void handle(Type type, String param) {
EventHandle eventHandle = eventHandleMap.get(type);
eventHandle.handle(param);
}
}
测试
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
EventContext bean = context.getBean(EventContext.class);
bean.handle(Type.END, "1212");
}
}
输出
我们可以改变类型去调用对应的算法。