我有以下场景,我正在努力为。。。
- 我有一个订阅了pub子主题的端点,这个特定的pub子话题有10种不同类型的通知/消息可以读取
以下是接口
public interface Handler {
void handle(String msg);
}
以下是事件处理程序
public class TeamMemberHandler implements Handler {
@Override
public void handle(String msg) {
}
}
下面是pubsub侦听器类,我希望不再为每个事件使用10种不同的切换情况。
public class PubSubListener {
// garbage quick example
@PostMapping("/pubsublistener")
private String pubsublistener(@RequestBody String msg) {
Map<String, Object> map = new Gson.fromJson(msg, HashMap.class);
String event = (String)map.get("rootElement");
// want to move away from this
switch(event){
case "1":
break;
.
.
.
case "10":
break;
default:
break;
}
}
}
我想做一些以下的事情。。。其中我有一个String中每个事件类型的映射,以及与之相关的处理程序
但是,不可能在下面的代码中执行handler.handle((。我该如何实现这一目标?
Map<String, Class<? extends Handler>> handlers = new HashMap<>();
handlers.put("TeamMemberEvent", TeamMemberHandler.class);
handlers.put("OtherTypeOfEvent", OtherTypeOfHandler.class);
Class<? extends Handler> handler = handlers.get(event);
handler.handle(msg);
我认为您误解了设计模式。它们通常是人们发现一种语言被反复用于解决比该语言的内置功能更大的问题的方式。
在您的情况下,您希望在java.util
包中使用Map
,它是该语言的内置工具。假设您有一个类型为<String, ? extends Handler>
的Map
,您可以通过查找String
的值来获得? extends Handler
。这方面的一个例子可能看起来像:
@PostMapping("/pubsublistener")
private String pubsublistener(@RequestBody String msg) {
Map<String, Object> map = new Gson.fromJson(msg, HashMap.class);
String event = (String)map.get("rootElement");
Handler handler = handlers.get(event);
handler.handle(event);
}
请注意,在使用此方法之前,需要使用处理程序和将用于查找它们的字符串填充Map
。这是通过Map
的.put(key, value)
方法完成的,在您的情况下,该方法将字符串作为键,将处理程序作为值。
第一个选项-如果处理程序在构造函数中不接受任何参数,则可以执行以下操作:
private final Map<String, Supplier<Handler>> handlersByEvent = Map.of(
"1", TeamMemberHandler::new,
"2", OtherTypeOfHandler::new
);
则在::pubsublistener
:
...
Supplier<Handler> handlerBuilder = handlersByEvent.get(map.get("rootElement"));
Handler handler = handlerBuilder.get();
handler.handle(msg);
第二个选项-为处理程序使用一堆方法而不是类:
private final Map<String, Consumer<String>> handlersByEvent = Map.of(
"1", this::handleTeamMemberMethod,
"2", this::handleOtherTypeOfMethod
);
则在::pubsublistener
:
...
Consumer<String> handler = handlersByEvent.get(map.get("rootElement"));
handler.accept(msg);
可能还有其他更好的方法。。。