1) Publishers-Subscriber / Observer Pattern (Communication) Intent: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. Structure: Subject +Attach(o: Observer) +Detach(o: Observer) +Notify() ConcreteSubject +subject Observer +Update() ConcreteObserver Participant Classes: Subject: Keeps track of its observers. Provides an interface for attaching and detaching Observer objects Observer: Defines an interface for update notification Concrete Subject: The object being observed. Stores state of interest to Concrete Observer objects. Sends a notification to its observers when its state changes Concrete Observer: The observing object. It stores state that should stay in consistent with the subject. Implements the Observer update interface to keep its state consistent with the participants. Example: Weather Information system The weather Station will be broadcasting the current weather conditions like temperature, humidity and biometric pressure. We have to create an application which receives the weather conditions and displays them in different forms. (i.e. displaying the current weather conditions, displaying weather statistics). All displays will be updating the weather conditions in real time, as and when the new conditions are recorded. Pattern Instance: Subject: Weather Station Observer: User Concrete Subject: Weather Data Concrete Observer: ForecastDisplay, CurrentConditionDisplay Use Case Diagram: System Forecast Display Weather Data User Weather Station CurrentCondition Display Class diagram: ForecastDisplay -currentPressure: float -lastPressure: float +ForecastDisplay(Observable) +update(Observable, Object) +display() WeatherData -temperature: float -pressure: float -humidity: float +getTemperature(): float +getPressure(): float +getHumidity(): float +measurementschanged(): float +setMeasurements(theTemperature: float, thePressure: float, theHumidity: float): float CurrentConditionDisplay -temperature: float -humidity: float +CurrentConditionDisply(Observable) +update(Observable, Object) +display() Sequence Diagram: WeatherStation +main(Strings) : Weather Data : CurrentCondition Display : Forecast Display : Weather Station : User 1 : setMeasurements NoChange() 2 : Display Current Condition() 3 : display() 4 : ChangeInWeather() 5 : DisplayForecastData() 6 : forecast data() Collaboration Diagram: : Forecast Display : Weather Data : User : Weather Station Java Code: WeatherData.java import java.util.Observable; public class WeatherData extends Observable { private float temperature; public float getTemperature() { return temperature; } private float pressure; public float getPressure() { return pressure; } private float humidity; public float getHumidity() { return humidity; : CurrentCondition Display } public void measurementschanged(){ setChanged(); notifyObservers(); } public void setMeasurements(float theTemperature, float theHumidity, float thePressure){ temperature=theTemperature; pressure=thePressure; humidity=theHumidity; measurementschanged(); } } ForeCastDisplay.java: import java.util.Observable; import java.util.Observer; public class ForeCastDisplay implements Observer { private float currentPressure = 29.92f; private float lastPressure; public ForeCastDisplay(Observable observable) { observable.addObserver(this); } public void update(Observable observable, Object arg) { if (observable instanceof WeatherData) { WeatherData weatherData = (WeatherData)observable; lastPressure = currentPressure; currentPressure = weatherData.getPressure(); display(); } } public void display() { System.out.print("Forecast: "); if (currentPressure > lastPressure) { System.out.println("Improving weather on the way!"); } else if (currentPressure == lastPressure) { System.out.println("More of the same"); } else if (currentPressure < lastPressure) { System.out.println("Watch out for cooler, rainy weather"); } } } CurrentConditionDisplay.java: import java.util.Observable; import java.util.Observer; public class CurrentConditionDisplay implements Observer { private float temperature; private float humidity; Observable observable; public CurrentConditionDisplay(Observable observable) { this.observable = observable; observable.addObserver(this); } public void update(Observable obs, Object arg) { if (obs instanceof WeatherData) { WeatherData weatherData = (WeatherData)obs; this.temperature = weatherData.getTemperature(); this.humidity = weatherData.getHumidity(); display(); } } public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity"); } } The Client: public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionDisplay currentConditions = CurrentConditionDisplay(weatherData); ForeCastDisplay forecastDisplay = new ForeCastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } } Output: Forecast: Improving weather on the way! Current conditions: 80.0F degrees and 65.0% humidity Forecast: Watch out for cooler, rainy weather Current conditions: 82.0F degrees and 70.0% humidity Forecast: More of the same Current conditions: 78.0F degrees and 90.0% humidity new