web-dev-qa-db-ja.com

単一の責任に準拠するアプリケーションの構造化

AircraftManagerオブジェクトのリストとAircraftオブジェクトのリストを追跡するクラスAircraftListenerがあります。

DataSource(SQL関連ではないカスタムクラス)オブジェクトは外部ソースから情報を取得し、データソースはメッセージをデコードし、航空機の適切なロジック、つまりsetAltitude、setHeadingを呼び出します。このプログラムは、航空機をライブマップにプロットするように設計されています。

aircraftでセッターを呼び出すと、AircraftManagerに登録されている各AircraftListeneronAircraftUpdate(Aircraft aircraft, String fieldName, Object fieldValue)メソッドがトリガーされます

まず最初に、AircraftAircraftManagerの参照を保持して、イベントリスナーのメソッドを呼び出すようにする必要があります。

public void setAltitude(int altitude) {
    if (this.altitude != altitude) {
        this.altitude = altitude;
        this.aircraftManager.getListeners().forEach((aircraftListener ->
                aircraftListener.onAircraftValueChanged(this, "altitude", longitude)));
    }
}

これはまた、AircraftManagerがすべてのAircraftListenerとAircraftを保持する責任があることを意味します。

私の質問は、このソリューションが満足できるものであるかどうか、あなたが行うどんな改善/変更でもあります。また、クラスはリスナーを1つの航空機ではなくすべての航空機に追加することを望まないことにも注意してください。

1
cobra12

提供したサンプルコードは、EventBusと呼ばれるもののバリアントのように感じられます。ここで、コンシューマは気になるイベントのタイプに登録できます。 EventBusの単一の責任は、特定のタイプのイベントを、そのイベントに登録しているすべてのリスナーに配信することです。

リスニングコードは、受信するイベントのタイプ(または基本タイプ)を登録します。疑似コードでは、次のようになります。

_eventBus.register<AirplaneEvent>(event -> onAircraftChanged(event));
_

方程式のプロデューサー側で、特定のイベントを公開します。

_public void setAltitude(int altitude) {
    if (this.altitude != altitude) {
        this.altitude = altitude;
        this.eventBus.publish(new AltitudeChangedEvent(this, altitude));
    }
}
_

別のソリューションは、単にパブリッシュ/サブスクライブメッセージバスです。

これらの各概念では、パブリッシュおよびサブスクライブの概念は、イベントをリスナーに配信する責任の不可欠な部分です。さて、この例に表示されていないのは、リスナーで行ったforEach()呼び出しです。それは、EventBusまたはメッセージバスの責任です。 EventBusの内部には、リスナーが登録したイベント/メッセージのみを配信するフィルタリングロジックがあります。 publish()を呼び出すクラスに公開されているリスナーはありません。

配信不能キューの処理または未処理のイベントの管理を何らかの方法で行う必要がある場合、それはEventBusまたはメッセージキューの責任です。サブスクライバーまたはパブリッシャーの役割のコードを変更する必要はありません。

2
Berin Loritsch