PHP design pattern-Observer pattern
Concept
The observer mode is a behavior mode that defines a one-to-many dependency between objects so that when the state of an object changes, all objects dependent on it are notified and automatically refreshed.
When the state of an object changes, it will affect the changes of other objects. in this case, the Observer Mode can be used.
The observer mode conforms to the interface isolation principle and achieves loose coupling between objects.
Alias
Publish-Subscribe Mode
Model-View Mode
Source-listener Mode
Subordinate mode
Role
Abstract topic: it stores reference of all observer objects in one aggregation. each topic can have any number of observers. Abstract topic provides an interface to add and delete observer objects.
ConcreteSubject: stores the status in a specific observer object, and sends a notification to all registered observers when the status of the subject changes.
Abstract Observer: defines an interface for all specific observers and updates themselves when receiving topic notifications.
ConcreteObserver: implements the update interface required by the abstract observer role to coordinate its status with the topic status.
UML diagram
Code
Sample code
SplSubject and SqlOberver interfaces have been provided in php spl. the source code is as follows:
/** * The SplSubject interface is used alongside * SplObserver to implement the Observer Design Pattern. * @link http://php.net/manual/en/class.splsubject.php */interface SplSubject { /** * Attach an SplObserver * @link http://php.net/manual/en/splsubject.attach.php * @param SplObserver $observer * The SplObserver to attach. *
* @return void * @since 5.1.0 */ public function attach (SplObserver $observer); /** * Detach an observer * @link http://php.net/manual/en/splsubject.detach.php * @param SplObserver $observer * The SplObserver to detach. *
* @return void * @since 5.1.0 */ public function detach (SplObserver $observer); /** * Notify an observer * @link http://php.net/manual/en/splsubject.notify.php * @return void * @since 5.1.0 */ public function notify ();}/** * The SplObserver interface is used alongside * SplSubject to implement the Observer Design Pattern. * @link http://php.net/manual/en/class.splobserver.php */interface SplObserver { /** * Receive update from subject * @link http://php.net/manual/en/splobserver.update.php * @param SplSubject $subject * The SplSubject notifying the observer of an update. *
* @return void * @since 5.1.0 */ public function update (SplSubject $subject);}
The following code is written based on the two spl interfaces:
_ Observers) {$ this-> _ observers [] = $ observer ;}} /*** implement the method of removing the observer ** @ param SplObserver $ observer */public function detach (SplObserver $ observer) {if (false! ==( $ Index = array_search ($ observer, $ this-> _ observers) {unset ($ this-> _ observers [$ index]);} /*** method for implementing the prompt information */public function using Y () {foreach ($ this-> _ observers as $ observer) {$ observer-> update ($ this) ;}/ *** set quantity ** @ param $ count */public function setCount ($ count) {echo "data size plus ". $ count.'
';}/*** Set points ** @ param $ integral */public function setIntegral ($ integral) {echo "add points". $ integral .'
';}}/*** Class Observer1 observer 1 */class Observer1 implements SplObserver {public function update (SplSubject $ subject) {$ subject-> setCount (10 );}} /*** Class Observer2 Observer 2 */class Observer2 implements SplObserver {public function update (SplSubject $ subject) {$ subject-> setIntegral (10 );}} /*** Class Client */class Client {/*** test method */public static function test () {// initialize the topic $ subject = new Subject (); // initialize observer 1 $ observer1 = new Observer1 (); // initialize Observer 2 $ observer2 = new Observer2 (); // add observer 1 $ subject-> attach ($ observer1); // add Observer 2 $ subject-> attach ($ observer2 ); // message prompt $ subject-> notify Y (); // output: the data volume plus 1 points plus 10 // remove the observer $ subject-> detach ($ observer1 ); // message $ subject-> notify (); // output: the data volume increases by 1 point plus 10 points plus 10} // run the test Client: test ();
Running result
Data volume plus 10 credits plus 10 credits plus 10 credits
Advantages and disadvantages
Advantages
The coupling between the observer and the topic is small;
Supports Broadcast Communication;
Disadvantages
Since the observer does not know the existence of other observers, it may have no idea about the final cost of changing the target. This may cause unexpected updates.
Applicable scenarios
When an abstract model has two aspects, one of which depends on the other.
When changing an object, you need to change other objects at the same time without knowing how many objects are to be changed.
When an object must notify other objects, it cannot assume who the other objects are. In other words, you do not want these objects to be tightly coupled.