This article will be pretty short.
Imagine you have a weather station and you should provide weather info for other businesses and government alerting system (they will use this information for informing people).
For implementing this we will use Observer pattern. Observer pattern has two parts Observable
and Observer
.
Observable
is the weather station that sends WeatherInfo
to subscribers.
interface Observable{ void add(Observer observer); void remove(Observer observer); void sendNotification(T notification); }
This the data class that will be sent by weather station to Observers:
class WeatherInfo { private final Instant date; private final int temperature; private final int humidity; WeatherInfo(Instant date, int temperature, int humidity) { this.date = date; this.temperature = temperature; this.humidity = humidity; } Instant getDate() { return date; } int getTemperature() { return temperature; } int getHumidity() { return humidity; } @Override public String toString() { return "WeatherInfo{" + "date=" + date + ", temperature=" + temperature + ", humidity=" + humidity + '}'; } }
And the Observable (it is generic in our case, but really could be called WeatherStation in this concrete example):
class ObservableImplimplements Observable { List > observers = new ArrayList<>(); @Override public void add(Observer observer) { observers.add(observer); } @Override public void remove(Observer observer) { observers.remove(observer); } @Override public void sendNotification(T notification) { observers.forEach(observer -> observer.notify(notification)); } }
Let’s see how Observers are implemented:
interface Observer{ void notify(T notification); }
As we said earlier there are at least two types of systems that are interested in data provided by our weather station, AlertSystem
used by the government and InfoSystem
used by some private companies for building devices with displays – they are Observers waiting to received data from Observable (WeatherStation):
AlertSystems reacts only defined threshold is violated:
class AlertsSystem implements Observer{ private final int minTemperature; private final int maxTemperature; AlertsSystem(int minTemperature, int maxTemperature) { this.minTemperature = minTemperature; this.maxTemperature = maxTemperature; } @Override public void notify(WeatherInfo notification) { if (notification.getTemperature() > maxTemperature || notification.getTemperature() < minTemperature) { System.out.println(String.format("ALERT: On %s, temperature will be: %d", notification.getDate(), notification.getTemperature())); } } }
InfoSystem displays available information to end-user:
class InfoSystem implements Observer{ @Override public void notify(WeatherInfo notification) { System.out.println(String.format("Weather information for %s, temperature=%s C, humidity=%d%%", notification.getDate(), notification.getTemperature(), notification.getHumidity())); } }
Now let's see the WeatherStation
(Observable) that will notify daily AlertSystem and InfoSystem (Observers):
class Main { public static void main(String[] args) { ObservableweatherStation = new ObservableImpl<>(); AlertsSystem alertsSystem = new AlertsSystem(0, 35); InfoSystem infoSystem = new InfoSystem(); weatherStation.add(infoSystem); weatherStation.add(alertsSystem); //weather station reads info from sensors and notifies subscribers WeatherInfo monday = new WeatherInfo(LocalDate.parse("2020-03-27") .atStartOfDay(ZoneId.systemDefault()).toInstant(), -1, 75); weatherStation.sendNotification(monday); WeatherInfo thursday = new WeatherInfo(LocalDate.parse("2020-03-28") .atStartOfDay(ZoneId.systemDefault()).toInstant(), 4, 75); weatherStation.sendNotification(thursday); WeatherInfo wednesday = new WeatherInfo(LocalDate.parse("2020-03-29") .atStartOfDay(ZoneId.systemDefault()).toInstant(), 37, 75); weatherStation.sendNotification(wednesday); } }
Output produced by this code:
Weather information for 2020-03-26T22:00:00Z, temperature=-1 C, humidity=75% ALERT: On 2020-03-26T22:00:00Z, temperature will be: -1 Weather information for 2020-03-27T22:00:00Z, temperature=4 C, humidity=75% Weather information for 2020-03-28T22:00:00Z, temperature=37 C, humidity=75% ALERT: On 2020-03-28T22:00:00Z, temperature will be: 37