我假設與subscribers.OfType<IHandle<T>>();
你想得到的所有類型的訂閱者IHandle<T>
其中T
是消息的類型,對不對?
在Java中,你必須稍微改變你的代碼,因爲類型擦除你不能提供這樣的類型。
假設你有每種類型/類單手柄,你可以做這樣的事情:
interface IHandle<T> {
Class<T> getMessageType(); //needed to query the handle for the supported class
void handle(T message);
}
用於創建接口的實現,你有幾種選擇:
制定實施每類:
class SpecialMessageHandle implements IHandle<SpecialMessage> {
public Class<SpecialMessage> getMessageType() { return SpecialMessage.class; }
public handle(SpecialMessage message) { ... }
}
或者通過類作爲參數:
class Handle<T> implements IHandle<T> {
Class<T> messageClass;
public Handle(Class<T> msgClass) { messageClass = msgClass; }
public Class<T> getMessageType() { return messageClass; }
public handle(T message) { ... }
}
然後,您可能會有一個地圖消息類來處理類並處理訂閱者的類(例如,在Guava Multimap之):
Map<Class<?>, IHandle<?>> handles = ...;
Multimap<IHandle<?>, Subscriber> subscribers = ...;
請注意,我用Class<?>
這裏,因爲我不知道是否有一個共同的超類或接口的類。如果你有一個共同的超類或接口X
那麼你會使用Class<? extends X>
。
另外請注意,我用IHandle<?>
因爲在Java中鍵和值需要同時支持不同的密鑰使用相同的通用類型,你無法定義的方式映射,即你不能做Map<Class<T>, IHandle<T>>
其中每個鍵會是不同的T
,但只允許一個適合關鍵的值。
添加手柄是這樣的:
handles.put(handle.getMessageType(), handle);
查詢該地圖信息,然後將這樣的工作:
IHandle<?> handle = handles.get(message.getClass());
Collection<Subscriber> handleSubscribers = subscribers.get(handle );
需要注意的是,如果你想獲得超類的用戶也是如此(例如,如果SpecialMessage extends Message
以及你想要訂閱Message
的那些人),那麼你需要走上類層次結構。
這裏是你願意爲一個水平了怎麼辦:
handles.get(message.getClass().getSuperclass());
for(Class<?> interface : message.getClass().getInterfaces()) {
handles.get(message);
}
嗯可以有0 - N的處理程序的類型。不能使用Java 8 Streams等等? – Anders 2014-09-02 12:51:45
Java btw中沒有內置協變/反變量? – Anders 2014-09-02 12:54:35
做了一些更多的研究,看起來像Covariance可能在Java中,但反變換不是,無賴 – Anders 2014-09-02 12:58:45