私のクラスはもともと複数の別々のaddAListener()
addBListener()
とremoveAListener
などから始まりました。これは1つのクラスでそれほど悪くはありませんでしたが、クラスが別のクラスによって内部的に使用され、拡張リスナーが伝播すると、instanceofのチェーンを短絡する良い方法はありますか?
簡単な解決策は、単一のインターフェイスを使用してinstanceof
でリスナーを整理することです:
public interface Listener {
}
public class ListenerA extends Listener {
}
public class ListenerB extends Listener {
}
public class ListenerC extends Listener {
}
List<ListenerA> ofListenersA = new List<>();
List<ListenerB> ofListenersB = new List<>();
List<ListenerC> ofListenersC = new List<>();
void addListener(Listener listener) {
if (listener instanceof ListenerA) {
ofListenersA.add(listener);
return;
}
if (listener instanceof ListenerB) {
ofListenersB.add(listener);
return;
}
if (listener instanceof ListenerB) {
ofListenersB.add(listener);
return;
}
}
void removeListener(Listener listener) {
if (listener instanceof ListenerA) {
ofListenersA.remove(listener);
return;
}
if (listener instanceof ListenerB) {
ofListenersB.remove(listener);
return;
}
if (listener instanceof ListenerB) {
ofListenersB.remove(listener);
return;
}
}
しかし、今、私はあなたがいないswitch
クラスでできる限り独占的に各instanceof
を評価する必要があります。
私は多くの種類のリスナーをチェックする必要がないため、これは最適化を求める試みではありません。むしろ、オブジェクト指向設計に関してこれが悪いアプローチであるかどうかについての質問です。インターフェース内の列挙を使用して
更新
短絡アプローチ:
enum ListenerType {
ListenerTypeA,
ListenerTypeB,
ListenerTypeC
}
public interface Listener {
ListenerType getType();
}
public class ListenerA extends Listener {
ListenerType getType() {
return ListenerType.ListenerTypeA;
}
}
public class ListenerB extends Listener {
ListenerType getType() {
return ListenerType.ListenerTypeB;
}
}
public class ListenerC extends Listener {
ListenerType getType() {
return ListenerType.ListenerTypeC;
}
}
List<ListenerA> ofListenersA = new List<>();
List<ListenerB> ofListenersB = new List<>();
List<ListenerC> ofListenersC = new List<>();
void addListener(Listener listener) {
switch (listener) {
case ListenerTypeA: {
ofListenersA.add(listener);
return;
}
case ListenerTypeB: {
ofListenersB.add(listener);
return;
}
case ListenerTypeC: {
ofListenersC.add(listener);
return;
}
}
}
void removeListener(Listener listener) {
switch (listener) {
case ListenerTypeA: {
ofListenersA.remove(listener);
return;
}
case ListenerTypeB: {
ofListenersB.remove(listener);
return;
}
case ListenerTypeC: {
ofListenersC.remove(listener);
return;
}
}
}
もしあなたが 'instanceof'を使っているのであれば、あなたのデザインはおそらく間違っています。なぜこれらのリスナーを別々に追跡したいのですが、それらを別々にする必要がある場合、なぜ単一の 'addListener'メソッドですか? – chrylis
このクラスのオブジェクトをプライベートメンバーとして使用する他のオブジェクトがあるためです。だから私は上からリスナーを提供する場合は、そのクラスの各リスナーを再度追加/削除する必要があります。私が別々のリスナーとしてそれらをすべて持っているのは、それぞれのイベントごとに個別にループするからです。 – Zhro
私は多くのopensourceプロジェクトを見てきましたが、一般的なリスナーのために単一のメソッドを使用する人は覚えていません。各リスナーに対してメソッドを作成し、直感的な名前を追加したいとします。 – Enzokie