PHP design pattern series-Observer pattern (Observer) 1. Pattern Definition
The Observer Mode is also called the publish/subscribe mode. this mode is used to implement the publish/subscribe function for objects. once the status of a subject object changes, the associated observer object receives a notification, and perform corresponding operations.
Splitting a system into a class that cooperates with each other has a bad side effect, that is, maintaining consistency between related objects. We do not want to make all kinds of close coupling to maintain consistency, which will cause inconvenience to maintenance, expansion and reuse. The Observer solves such coupling relationships.
Message queue systems and events all use the observer mode.
PHP defines two interfaces for the Observer Mode: SplSubject and SplObserver. SplSubject can be seen as the abstraction of the subject object, and SplObserver can be seen as the abstraction of the observer object. to implement the observer mode, you only need to implement the SplSubject of the subject object, the Observer object implements the SplObserver, and implement the corresponding method.
2. UML class diagram
3. Sample code
User. php
Observers = new \ SplObjectStorage ();}/*** Additional observer ** @ param \ SplObserver $ observer ** @ return void */public function attach (\ SplObserver $ observer) {$ this-> observers-> attach ($ observer );} /*** cancel the observer ** @ param \ SplObserver $ observer ** @ return void */public function detach (\ SplObserver $ observer) {$ this-> observers-> detach ($ observer);}/*** notification observer method ** @ return void */public function Y () {/** @ var \ SplObserver $ observer */foreach ($ this-> observers as $ observer) {$ observer-> update ($ this );}} /***** @ param string $ name * @ param mixed $ value ** @ return void */public function _ set ($ name, $ value) {$ this-> data [$ name] = $ value; // notify the observer user to be changed $ this-> Y ();}}
UserObserver. php
4. test codeTests/ObserverTest. php
Observer = new UserObserver ();}/*** test notification */public function testNotify () {$ this-> expectOutputString ('designpatterns \ Behavioral \ Observer \ User has been updated'); $ subject = new User (); $ subject-> attach ($ this-> observer); $ subject-> property = 123;}/*** Test subscription */public function testAttachDetach () {$ subject = new User (); $ reflection = new \ ReflectionProperty ($ subject, 'observers'); $ reflection-> setAccessible (true ); /** @ var \ SplObjectStorage $ observers */$ observers = $ reflection-> getValue ($ subject); $ this-> assertInstanceOf ('splobjectstore', $ observers ); $ this-> assertFalse ($ observers-> contains ($ this-> observer); $ subject-> attach ($ this-> observer ); $ this-> assertTrue ($ observers-> contains ($ this-> observer); $ subject-> detach ($ this-> observer ); $ this-> assertFalse ($ observers-> contains ($ this-> observer);}/*** Test update () call */public function testUpdateCalling () {$ subject = new User (); $ observer = $ this-> getMock ('splobserver'); $ subject-> attach ($ observer ); $ observer-> expects ($ this-> once ()-> method ('update')-> with ($ subject); $ subject-> Policy ();}}
5. SummaryThe observer mode removes the coupling between the subject and the specific observer, so that both sides of the coupling depend on abstraction rather than on specifics. So that changes on the other side will not be affected.