構築中の Android アプリ用に、軽量でスレッドセーフなアプリ内パブリッシュ/サブスクライブ メカニズムを作成しようとしています。私の基本的なアプローチは、各イベント タイプ T のリストを追跡し、IEventSubscriber<T>
タイプ T のペイロードを渡すことで、サブスクライブするオブジェクトにイベントを発行できるようにすることです。
私はジェネリック メソッド パラメーターを使用して、サブスクリプションがタイプ セーフな方法で作成されるようにしています。したがって、イベントを公開するときにサブスクリプション マップからサブスクライバーのリストを取得すると、それを のリストにキャストしても問題ないと確信していますがIEventSubscriber<T>
、これにより unchecked cast 警告が生成されます。
私の質問:
- チェックされていないキャストは実際にここで安全ですか?
- 購読者リストの項目が実装されているかどうかを実際に確認するにはどうすればよい
IEventSubscriber<T>
ですか? - (2) に厄介な反省が含まれていると仮定すると、ここで何をしますか?
コード (Java 1.6):
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
public class EventManager {
private ConcurrentMap<Class, CopyOnWriteArraySet<IEventSubscriber>> subscriptions =
new ConcurrentHashMap<Class, CopyOnWriteArraySet<IEventSubscriber>>();
public <T> boolean subscribe(IEventSubscriber<T> subscriber,
Class<T> eventClass) {
CopyOnWriteArraySet<IEventSubscriber> existingSubscribers = subscriptions.
putIfAbsent(eventClass, new CopyOnWriteArraySet<IEventSubscriber>());
return existingSubscribers.add(subscriber);
}
public <T> boolean removeSubscription(IEventSubscriber<T> subscriber,
Class<T> eventClass) {
CopyOnWriteArraySet<IEventSubscriber> existingSubscribers =
subscriptions.get(eventClass);
return existingSubscribers == null || !existingSubscribers.remove(subscriber);
}
public <T> void publish(T message, Class<T> eventClass) {
@SuppressWarnings("unchecked")
CopyOnWriteArraySet<IEventSubscriber<T>> existingSubscribers =
(CopyOnWriteArraySet<IEventSubscriber<T>>) subscriptions.get(eventClass);
if (existingSubscribers != null) {
for (IEventSubscriber<T> subscriber: existingSubscribers) {
subscriber.trigger(message);
}
}
}
}