I have the class AircraftManager
that keeps track of a list of Aircraft
objects and a list of AircraftListener
objects.
A DataSource
(custom class, not sql related) object retrieves information from an external source, the data sources decodes the message and calls appropriate logic on the aircraft, i.e setAltitude, setHeading. The program is designed to plot Aircraft onto a live map.
calling the setters on Aircraft should trigger the onAircraftUpdate(Aircraft aircraft, String fieldName, Object fieldValue)
method on each registered AircraftListener
in the AircraftManager
This first of all requires the Aircraft
to keep a reference of the AircraftManager
to invoke methods on the event listeners as such:
public void setAltitude(int altitude) {
if (this.altitude != altitude) {
this.altitude = altitude;
this.aircraftManager.getListeners().forEach((aircraftListener ->
aircraftListener.onAircraftValueChanged(this, "altitude", longitude)));
}
}
This also means AircraftManager has a responsibility to keep hold of all AircraftListeners as well as Aircraft.
My question is whether this solution is satisfactory, any improvements/changes you would make. It's also worth noting that a class will not want to add a listener upon a single aircraft, but all aircraft.
1 Answer 1
The example code you provided feels like a variant of something known as an EventBus
where consumers can register for the type of event they care about. The single responsibility for the EventBus is to deliver events of a specific type to all the listeners registering for that event.
The listening code would register for the type (or base type) of event it wants to receive. In pseudo code it would look like this:
eventBus.register<AirplaneEvent>(event -> onAircraftChanged(event));
In your producer side of the equation you would publish the specific event:
public void setAltitude(int altitude) {
if (this.altitude != altitude) {
this.altitude = altitude;
this.eventBus.publish(new AltitudeChangedEvent(this, altitude));
}
}
Another solution would simply be a publish/subscribe message bus.
In each of these concepts the idea of publish and subscribe are integral parts of the responsibility of delivering events to the listeners. Now, what you don't see in this example is the forEach()
call you did in the listener. That's the responsibility of the EventBus or Message Bus. Inside the EventBus would be the filtering logic to deliver only the events/messages that a listener had registered for. None of the listeners are exposed to the class calling publish()
If you needed to handle dead-letter queuing or managing unhandled events in some way, that is solely the responsibility of the EventBus
or message queue. None of the code from the subscriber or publisher role must change.
DataSource
(custom class, not sql related) object retrieves information from an external source, the data sources decodes the message and calls appropriate logic on the aircraft, i.e setAltitude, setHeading. The program is designed to plot Aircraft onto a live map.