Mike G
Mike G

Reputation: 4959

Observer Pattern in java, a better way?

The code below was taken from another SO post, I was wondering is there a better way of writing this code, because its kind of ugly to have a loop that notifies all the listener at the end of every implemented method. If this is silly forgive me, I am new to Java.

Note: I will be implementing more than one method in the interface, I will have 5 methods implemented:

import java.util.*;

interface HelloListener {
    public void someoneSaidHello();
}


class Initiater {
    List<HelloListener> listeners = new ArrayList<HelloListener>();

    public void addListener(HelloListener toAdd) {
        listeners.add(toAdd);
    }

    public void sayHello() {
        System.out.println("Hello!!");

        // Notify everybody that may be interested.
        for (HelloListener hl : listeners)
            hl.someoneSaidHello();
    }
}


class Responder implements HelloListener {
    @Override
    public void someoneSaidHello() {
        System.out.println("Hello there...");
    }
}

Upvotes: 2

Views: 1173

Answers (3)

Jiman
Jiman

Reputation: 185

When I implemented the Observer pattern as a student, I made it as an abstract class:

import java.util.ArrayList;

/**
 * The observer pattern.
 * @author jiman 
 */
public abstract class Observed {

    private ArrayList<Observer> observers;

    public Observed() { views = new ArrayList<Observer>(); }

    public void registerObserver(Observer o) { observers.add(o); }

    public void removeObserver(Observer o) { observers.remove(o); }

    // call this method upon a mutation of the state of this object
    public void notifyObservers() { for (Observer o : observers) o.update(); }

}

Observers will inherit from this interface and write their own update methods.

public interface Observer {

    public void update();

}

Upvotes: 2

Patricia Shanahan
Patricia Shanahan

Reputation: 26185

If there are multiple methods that need to notify all the listeners the loop can be refactored out into its own method that can be called from each of the notifying methods.

For example, the source code for javax.swing.AbstractButton has a firestateChanged() method for notifying listeners of a state change etc.

Upvotes: 2

Frank
Frank

Reputation: 15641

Two Classes exists in the JDK to help you do this.

Observer (Interface) and Observable (Class)

A small example on how to use them:

  class MyView implements Observer {

    public void update(Observable obs, Object x) {
      System.out.println("update(" + obs + "," + x + ");");
    }
  }

  /** The Observable normally maintains the data */
  class MyModel extends Observable {

    public void changeSomething() {
      // Notify observers of change
      setChanged(); // THIS IS IMPORTANT DON'T FORGET IT!
      notifyObservers();
    }
  }

Upvotes: 1

Related Questions