问题
trying to find an example of this, it's possible that I am not going the right way around it, or that my mind has over simplified the concept of the observer pattern.
I want to create a class that controls messages from a web service, and I want this class to monitor the changes of many other operations.
The observer pattern examples I have seen demonstrate many observers watching a single observable, can I (or should I) do this the other way round? What else should I be doing?
回答1:
Just register a single Observer instance in many Oservable instances.
You probably will want to pass Observable instance to Observer, whenever Observable updates, so that Observer knows which specific object updated it.
A trivial example:
interface Observer {
public update(Observable $observable);
}
class Observable() {
private $observers = array();
public function register(Observer $observer) {
$this->observers[] = $observer;
}
public function update() {
foreach($observers as $observer) {
$observer->update($this);
}
}
}
$observer = new ObserverImplementation();
$observable1->register($observer);
$observable2->register($observer);
$observable1->update();
$observable2->update();
Also you might want to lookup the Mediator pattern.
Here's pretty nice implementation of it: Symfony Event Dispatcher
回答2:
I think it's really important to remember that design patterns are suggestions and not absolutes. If they can be modified to better fit your needs then they should.
And yes in this case it can most definitely be done. Your observers will simply need to register with more than one observable object.
When one of your observable objects will notify it's observers it will simply loop on a list of references to tell them to update. It really doesn't matter if these references are shared with other observable objects.
回答3:
I subscribe to the idea that 1 class performs 1 core task. If it were me, I would build an observer interface, create multiple observer implementations, and manage all of those observers with some ObserverManager class.
Doing it this way will separate all of your business concerns, and will afford a finer level of granularity for testing.
Unless the "changes of many other operations" can be typified as the same kind of observable "change." At that point the the single observer makes sense.
回答4:
From GoF (implementation section of the Observer pattern), "Observing more than one subject. It might make sense in some situations for an observer to depend on more than one subject. For example, a spreadsheet may depend on more than one data source. It's necessary to extend the Update interface in such cases to let the observer know which subject is sending the notification. The subject can simply pass itself as a parameter in the Update operation, thereby letting the observer know which subject to examine."
The answer from Mchl already contains the example. I am just adding the reference from GoF that it will not be a bad practice if you need to do this.
回答5:
This is certainly doable. All you need to do is pass add a parameter to the oberver function/method that points at the observable.
来源:https://stackoverflow.com/questions/4829462/can-an-observer-observe-multiple-observables