1 / 17

The Observer Pattern

The Observer Pattern. 1 Introduction The observer pattern is very often used : for example to link view of a system (e.g. a GUI, its view layer) to the model of system (i.e. its core, its logic layer) 2 Example : Weather Monitoring Application

nita
Download Presentation

The Observer Pattern

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Observer Pattern 1 Introduction • The observer pattern is very often used : for example to link view of a system (e.g. a GUI, its view layer) to the model of system (i.e. its core, its logic layer) 2 Example : Weather Monitoring Application • A weather station : a physical device which monitors humidity, temperature, and pressure. • A separate display with different views: • Current Conditions; • Weather Stats; • Forecast. • A weather data object who knows how to talk to the physical weather station and updates the displays.

  2. The WeatherData is like a device driver : it is provided by the WeatherStation manufacturer

  3. Our job is to implement measurementsChanged(), which is called automatically, to update our display’s views. • Obviously, there may be other views that may need to be supported in the future ...

  4. But there are issues: We are coding to a concrete implementation, not to interfaces; For every new display we need to alter code of WeatherData (bad for third party developers : we will have to give them the code of WeatherData) We have no way to add or remove views at run time; We have not encapsulated the parts that change.

  5. 3 Introducing the Observer Pattern • Imagine a newspaper business : they publish a newspaper. People subscribe to it and receive the newspaper for as long as they subscribe to it. • Think of RSS : a web master sets up a RSS feed that people subscribe to. Subscribers get notified when the feed changes. They may unsubscribe at any time. • Publisher + Subscribers = Observer Pattern • Publisher is also sometimes called the Subject or Observable • Subscribers are also sometimes called Listeners or Observers • “The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.”

  6. Subject : Sends a notification message to one or many observers when there is a change in state. Along with the message, provides information on the state that has changed. Observers : The objects that want to be notified about changes in the Subject’s state. Contains signatures for registering, removing, and notifying observers. Contains Update method so that information can be sent from Subject to Observer.

  7. The fields for humidity, pressure, and temperature represent the state of the Subject. Questions: Which field is used for storing the list of Observers? How does an Observer add itself to this list?

  8. public class WeatherData : ISubject { private float temperature; private float humidity; private float pressure; private ArrayList Observers; public WeatherData() {observers = new ArrayList();} public void MeasurementsChanged() {NotifyObserver();} //The Weather Station Device should update the state and // call MeasurementsChanged() : we set up a fake method // to simulate this and allow testing public void SetMeasurements(float t, float h, float p){ temperature = t; humidity = h; pressure = p; MeasurementsChanged(); }

  9. public void RegisterObserver(IObserver o) { observers.Add(o); } public void RemoveObserver(IObserver o) { int i = observers.IndexOf(o); if(i >= 0) observers.Remove(o); } public void NotifyObserver() { foreach(IObserver observer in observers) observer.Update(temperature,humidity,pressure); } }//WeatherData Next : A concrete display must implement the IObserver interface and a IDisplayElement (since all display elements must implement their own display method)

  10. public class CurrentConditionsDisplay : IObserver, IDisplayElement { private float temperature; private float humidity; private Isubject weatherData; //needed to unsubscribe ... public CurrentConditionsDisplay(ISubject weatherData) { this.weatherData = weatherData; weatherData.RegisterObserver(this); } public void Update(float t, float h, float p) { temperature = t; humidity = h; display(); } private void Display() { Console.WriteLine(“Current conditions: “ + temperature + “degrees” + humidity + “%humidity”); } }

  11. Exercise: create the UML class diagram for the system so far. • Since we do not a physical Weather Station device we set up a software one to allow simulation: public class WeatherStation { public static Main() { WeatherDataweatherData = new WeatherData(); //create the subject //create an observer, i.e. a display CurrentConditionsDisplaycurrentDisplay = new CurrentConditionsDisplay(weatherdata); weatherdata.SetMeasurements(80, 65, 30.4f); weatherdata.SetMeasurements(82, 70, 29.2f); } } • Exercise: in the lab create the Weather System as suggested above, add a least another kind of display (e.g. StatisticsDisplay which displays record temperatures).

  12. 4 Push vs Pull • The notification mechanism we have just used is called the “push” model because the subject is pushing information to the observers: public void NotifyObserver() { foreach(IObserver observer in observers) observer.Update(temperature,humidity,pressure); } • This not always suitable : • what happens if the state of the subject changes? e.g. we add a wind direction sensor … • since not all the display need all the state of the subject this approach may be a bit of a waste. E.g. what if part of the state is a large chunk of data that uses a lot memory? • what if part of the state of the subject is updated only very rarely?

  13. An alternative to the “Push” model is the “Pull” model. The Observer pulls the information that is needed from the Subject. We can make a simple change to the IObserver interface: public interface IObserver { void Update(ISubject subject); } • Lab Exercise: change your project so that it uses the Push model for the Weather Station. Note: • If we already have a reference to the subject with the observer … then simply changing the update method of interface to void update(); will be sufficient • Downcasting can be achieved by ((WeatherData)(Object)subject) • Also you will need to provide a public getter method for the data members of the subject (or replace them with C# properties as in publicfloat humidity { privateset {humidity = value;} get { return humidity;} })

  14. 5 Refactoring the Weather Station example The WeatherData (the subject) and the Displays (the observers) contain a lot of code which is not specific to the application but relate to the Observer Pattern... We can re-factor the code to abstract away the Subject and Observer functionality this will make it reusable.

  15. Lab exercise : Create a new project that uses abstract classes instead of interfaces so that re-use of the Observer Pattern implementation is possible.

  16. This new design whilst facilitating re-use is less flexible since we have to subclass (and this can only be done once in a single inheritance language such as C# or Java) from the Subject and Observer classes to get the benefits of re-using the observer pattern implementation ... 6 Conclusions on the Observer Pattern • The observer pattern defines a loosely coupled (especially in its push version) solution for one to many notifications between a subject and observers. • The order of the notifications should not be depended upon. • .NET framework 4 includes a new System.IObservable<T> and System.IObserver<T> interfaces that provide a generalized mechanism for push-based notifications. See http://msdn.microsoft.com/en-us/library/ee850490.aspx (but that is obviously very specific to C#)

  17. Java has a java.util.Observable class that can be subclassed and a an interface Observer (but that is obviously specific to Java) • There are other implementations of the observer pattern than the ones we have seen (e.g. using events and delegates in C#) • What is the most important is recognise when the Observer pattern should be used, and know a basic implementation of it.

More Related