Gang of Four Behavioural pattern: Observer
Behavioural Pattern
A way of notifying change to a number of classes. Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
In the Observer pattern there is one Observable and there are many Observers.
The idea is that when something specific happens with the Observable all Observers are notified of this happening.
To get the code for this example:
git clone https://github.com/spotadev/gangoffour.git
In src/main/java navigate to this package:
com.javaspeak.designpatterns.go4.behavioural.observer
You can run the code from the main method of:
ObserverApplication
In this example we have an Observable called ObservableImpl which adds three different Observers to its list of Observers using its addObserver(..) method. Each of the Observers implements Observer.
ObservableImpl then calls notifyObservers(ObservableEvent e) to inform all subscribed observers of a new happening. The happening is encapsulated in a ObservableEventImpl which holds a messages. The message is "Hello Everyone!".
Internally the notifyObservers(..) method loops through all its subscribed Observers and calls the receiveObservableEvent(ObservableEvent e ) on each of them.
Each Observer then retrieves the message from then ObservableEvent and prints it to the console.
package com.javaspeak.designpatterns.go4.behavioural.observer;
import java.util.ArrayList;
import java.util.List;
/**
* Text book description:
* <ul>
* Observer: A way of notifying change to a number of classes. Define a one-to-many dependency
* between objects so that when one object changes state, all its dependents are notified and
* updated automatically.
* </ul>
* This example uses the Observer pattern.
* <p>
* In the Observer pattern there is one Observable and there are many Observers.
* <p>
* The idea is that when something specific happens with the Observable all Observers are notified
* of this happening.
* <p>
* In this example we have a Observable called ObservableImpl which adds three different Observers
* to its list of Observers using its addObserver(..) method. Each of the Observers implements
* Observer.
* <p>
* ObservableImpl then calls notifyObservers(ObservableEvent e) to inform all subscribed observers
* of a new happening. The happening is encapsulated in a ObservableEventImpl which holds a
* messages. The message is "Hello Everyone!".
* <p>
* Internally the notifyObservers(..) method loops through all its subscribed Observers and
* calls the receiveObservableEvent(ObservableEvent e ) on each of them.
* <p>
* Each Observer then retrieves the message from then ObservableEvent and prints it to the console.
*
* @author John Dickerson - 22 Feb 2020
*/
public class ObserverApplication implements Observable {
List<Observer> observers = new ArrayList<Observer>();
@Override
public void addObserver( Observer observer ) {
observers.add( observer );
}
@Override
public void notifyObservers( ObservableEvent observableEvent ) {
for ( Observer observer : observers ) {
observer.receiveObservableEvent( observableEvent );
}
}
public void runExample() {
// This class is the Observable
// First we create some Observers
Observer observerOne = new ObserverImpl( "ObserverOne" );
Observer observerTwo = new ObserverImpl( "ObserverTwo" );
Observer observerThree = new ObserverImpl( "ObserverTwo" );
// Next we subscribe those observers so that they are observing the Observable. "Observing"
// in this example means they are waiting for ObservavleEvents. In other words the Observers
// are waiting for their receiveObservableEvent(..) method to be called.
addObserver( observerOne );
addObserver( observerTwo );
addObserver( observerThree );
// The Observable (this class) loops through its sunscribed observers and calls
// receiveObservableEvent(..) on each of them. A ObservableEvent is passed to each of the
// Observers which has the message, "Hello Everyone!" in it. The Observers in turn print
// the message to the console.
notifyObservers( new ObservableEventImpl( "Hello Everyone!" ) );
}
public static void main( String[] args ) {
ObserverApplication application = new ObserverApplication();
application.runExample();
}
}
package com.javaspeak.designpatterns.go4.behavioural.observer;
/**
* The class which is having its state observed implements this interface.
* <p>
* When a certain event happens the Observable will notify all its subscribed observers that the
* event has occurred.
*
* @author John Dickerson - 22 Feb 2020
*/
public interface Observable {
/**
* Add a subscribed observer to its list of observers. The subscribed observers can be said
* from that point in time to be listening to ObservableEvents.
*
* @param observer
* The observer which has subscribed to the ObservableEvents
*/
public void addObserver( Observer observer );
/**
* The Observable calls this method to inform all its subscribed observers that an
* ObservableEvent has occurred.
*
* @param observableEvent
* The ObservableEvent to inform all its subscribed observers that it has occurred.
* Internally the notifyObservers(..) method loops through all its subscribed observers
* and calls the receiveObservableEvent(..) method on each of them. Each of the subscribed
* observers in turn calls the getMessage() method on the ObservableEvent they received and
* prints the message to the console.
*/
public void notifyObservers( ObservableEvent observableEvent );
}
package com.javaspeak.designpatterns.go4.behavioural.observer;
/**
* Observers are interested in receiving ObservableEvents when a specific happening occurs in the
* Observable (ApplicationObserver).
*
* @author John Dickerson - 22 Feb 2020
*/
public interface Observer {
/**
* This method is called on each of the subscribed Observers when the Observable executes its
* notifyObservers( ObservableEvent observableEvent ) method.
*
* @param observableEvent
* The ObservableEvent to pass to the Observer
*/
public void receiveObservableEvent( ObservableEvent observableEvent );
}
package com.javaspeak.designpatterns.go4.behavioural.observer;
/**
* An ObservableEvent is an encapsulation of an event that has occurred in the Observable which its
* Observers have subscribed to (are listening to).
* <p>
* In this example the ObservableEvent has a message in it. It could also however have other
* attributes such as EventType.
*
* @author John Dickerson - 22 Feb 2020
*/
public interface ObservableEvent {
/**
* The ObservableEvent has a message in it.
*
* @return message
*/
public String getMessage();
}
package com.javaspeak.designpatterns.go4.behavioural.observer;
/**
* An ObservableEvent is an encapsulation of an event that has occurred in the Observable which
* its Observers have subscribed to (are listening to).
* <p>
* In this example the ObservableEvent has a message in it. It could also however have other
* attributes such as EventType.
*
* @author John Dickerson - 22 Feb 2020
*/
public class ObservableEventImpl implements ObservableEvent {
private String message;
public ObservableEventImpl( String message ) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
}
package com.javaspeak.designpatterns.go4.behavioural.observer;
/**
* Observers are interested in receiving ObservableEvents when a specific happening occurs in the
* Observable (ApplicationObserver). ObserverImpl is the implementing class of Observer.
*
* @author John Dickerson - 22 Feb 2020
*/
public class ObserverImpl implements Observer {
private String observerName;
public ObserverImpl( String observerName ) {
super();
this.observerName = observerName;
}
@Override
public void receiveObservableEvent( ObservableEvent observableEvent ) {
System.out.println( observerName + " received event " + observableEvent.getMessage() );
}
}
Back: Gang of Four
Page Author: JD