策略模式的简单使用

简介

策略模式:定义了一系列的算法族,每一个算法都实现了接口的需要处理的方法,算法族可以互换。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");
    }
}

输出


image

我们可以改变类型去调用对应的算法。

你可能感兴趣的:(策略模式的简单使用)