Reputation: 23
I have an observer class below. my question is how could I set up up this class to listen(observe) to more than 1 subject?
public class Observer2 implements Observer {
private Subject robot;
public Observer2(Subject robot){
this.robot = robot;
robot.registerObserver(this);
}
@Override
public void update(){}
}
Upvotes: 1
Views: 402
Reputation: 503
A ConcreteObserver can observe more than one Subject simply calling many times the attach method that the Subjects provide.
If the question is instead:
The answer is that in the ConcreteObserver the update method must be overloaded to manage many times equal to the types of states that the ConcreteObserver has to observe.
The ConcreteObserver must have also an array of states to store the observed states of the Subjects, with some mechanism to avoid that state of the same type coming from different Subject influence the state of each other.
Upvotes: 0
Reputation: 727137
Use Java's Observer
and Observable
, which are set up for proper handling of multiple subjects:
class Robot extends Observable {
public void act() {
notifyObservers("Run!");
}
}
class Cyborg extends Observable {
public void act() {
notifyObservers("Hide!");
}
}
public class MyObserver implements Observer {
@Override
public void update(Observable subj, Object arg) {
if (subj instanceof Robot) {
System.out.println("Scary robot says " + arg);
} else if (subj instanceof Cyborg) {
System.out.println("Lovely cyborg says " + arg);
} else {
System.out.println("What's this? " + arg);
}
}
}
Registration is done differently:
// Construct observables
Robot r = new Robot();
Cyborg c = new Cyborg();
// Add observer to both of them
MyObserver o = new MyObserver();
r.addObserver(o);
c.addObserver(o);
r.act();
c.act();
Upvotes: 0
Reputation: 5506
You can have a Subject class which stores all the observers in a list.
public abstract class Subject
{
private ArrayList<Observer> observerList = new ArrayList<>();
public void attach(Observer observer)
{
observerList.add(observer);
}
/**
* Notifies observers to run execute
*/
protected void notifyObservers()
{
for(int i = 0; i < observerList.size(); i++)
{
observerList.get(i).update();
}
}
}
The typical Observer interface:
interface Observer
{
void update();
}
Thereafter, you can trigger the observers using the notifyObservers()
method.
Upvotes: 1
Reputation: 12513
Use a set.
public class MultiObserver extends Observer {
private final Set<Subject> observed = new HashSet<>();
public void observe(Subject s) {
if (observed.add(s))
s.registerObserver(this);
}
}
Upvotes: 0