diff --git a/Behavioral/Observer/Tests/ObserverTest.php b/Behavioral/Observer/Tests/ObserverTest.php
index 6a3f369..c263997 100644
--- a/Behavioral/Observer/Tests/ObserverTest.php
+++ b/Behavioral/Observer/Tests/ObserverTest.php
@@ -5,65 +5,16 @@ namespace DesignPatterns\Behavioral\Observer\Tests;
use DesignPatterns\Behavioral\Observer\User;
use DesignPatterns\Behavioral\Observer\UserObserver;
-/**
- * ObserverTest tests the Observer pattern.
- */
class ObserverTest extends \PHPUnit_Framework_TestCase
{
- protected $observer;
-
- protected function setUp()
+ public function testChangeInUserLeadsToUserObserverBeingNotified()
{
- $this->observer = new UserObserver();
- }
+ $observer = new UserObserver();
- /**
- * Tests the notification.
- */
- public function testNotify()
- {
- $this->expectOutputString('DesignPatterns\Behavioral\Observer\User has been updated');
- $subject = new User();
+ $user = new User();
+ $user->attach($observer);
- $subject->attach($this->observer);
- $subject->property = 123;
- }
-
- /**
- * Tests the subscribing.
- */
- public function testAttachDetach()
- {
- $subject = new User();
- $reflection = new \ReflectionProperty($subject, 'observers');
-
- $reflection->setAccessible(true);
- /** @var \SplObjectStorage $observers */
- $observers = $reflection->getValue($subject);
-
- $this->assertInstanceOf('SplObjectStorage', $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));
- }
-
- /**
- * Tests the update() invocation on a mockup.
- */
- public function testUpdateCalling()
- {
- $subject = new User();
- $observer = $this->createMock('SplObserver');
- $subject->attach($observer);
-
- $observer->expects($this->once())
- ->method('update')
- ->with($subject);
-
- $subject->notify();
+ $user->changeEmail('foo@bar.com');
+ $this->assertCount(1, $observer->getChangedUsers());
}
}
diff --git a/Behavioral/Observer/User.php b/Behavioral/Observer/User.php
index 0d2a817..6fd58d4 100644
--- a/Behavioral/Observer/User.php
+++ b/Behavioral/Observer/User.php
@@ -3,60 +3,42 @@
namespace DesignPatterns\Behavioral\Observer;
/**
- * Observer pattern : The observed object (the subject).
- *
- * The subject maintains a list of Observers and sends notifications.
+ * User implements the observed object (called Subject), it maintains a list of observers and sends notifications to
+ * them in case changes are made on the User object
*/
class User implements \SplSubject
{
/**
- * user data.
- *
- * @var array
+ * @var string
*/
- protected $data = array();
+ private $email;
/**
- * observers.
- *
* @var \SplObjectStorage
*/
- protected $observers;
+ private $observers;
public function __construct()
{
$this->observers = new \SplObjectStorage();
}
- /**
- * attach a new observer.
- *
- * @param \SplObserver $observer
- *
- * @return void
- */
public function attach(\SplObserver $observer)
{
$this->observers->attach($observer);
}
- /**
- * detach an observer.
- *
- * @param \SplObserver $observer
- *
- * @return void
- */
public function detach(\SplObserver $observer)
{
$this->observers->detach($observer);
}
- /**
- * notify observers.
- *
- * @return void
- */
+ public function changeEmail(string $email)
+ {
+ $this->email = $email;
+ $this->notify();
+ }
+
public function notify()
{
/** @var \SplObserver $observer */
@@ -64,21 +46,4 @@ class User implements \SplSubject
$observer->update($this);
}
}
-
- /**
- * Ideally one would better write setter/getter for all valid attributes and only call notify()
- * on attributes that matter when changed.
- *
- * @param string $name
- * @param mixed $value
- *
- * @return void
- */
- public function __set($name, $value)
- {
- $this->data[$name] = $value;
-
- // notify the observers, that user has been updated
- $this->notify();
- }
}
diff --git a/Behavioral/Observer/UserObserver.php b/Behavioral/Observer/UserObserver.php
index f2673ba..243e740 100644
--- a/Behavioral/Observer/UserObserver.php
+++ b/Behavioral/Observer/UserObserver.php
@@ -2,19 +2,28 @@
namespace DesignPatterns\Behavioral\Observer;
-/**
- * class UserObserver.
- */
class UserObserver implements \SplObserver
{
/**
- * This is the only method to implement as an observer.
- * It is called by the Subject (usually by SplSubject::notify() ).
+ * @var User[]
+ */
+ private $changedUsers = [];
+
+ /**
+ * It is called by the Subject, usually by SplSubject::notify()
*
* @param \SplSubject $subject
*/
public function update(\SplSubject $subject)
{
- echo get_class($subject).' has been updated';
+ $this->changedUsers[] = clone $subject;
+ }
+
+ /**
+ * @return User[]
+ */
+ public function getChangedUsers(): array
+ {
+ return $this->changedUsers;
}
}
diff --git a/Behavioral/Observer/uml/Observer.uml b/Behavioral/Observer/uml/Observer.uml
index 0e5ddef..b74d770 100644
--- a/Behavioral/Observer/uml/Observer.uml
+++ b/Behavioral/Observer/uml/Observer.uml
@@ -1,27 +1,26 @@
-
-
- PHP
- \DesignPatterns\Behavioral\Observer\User
-
- \DesignPatterns\Behavioral\Observer\UserObserver
- \DesignPatterns\Behavioral\Observer\User
- \SplSubject
-
-
-
-
-
-
-
-
-
-
-
- Fields
- Constants
- Constructors
- Methods
-
- private
-
-
+
+
+ PHP
+ \DesignPatterns\Behavioral\Observer\UserObserver
+
+ \DesignPatterns\Behavioral\Observer\UserObserver
+ \SplObserver
+ \DesignPatterns\Behavioral\Observer\User
+
+
+
+
+
+
+
+
+
+
+
+ Fields
+ Constants
+ Methods
+
+ private
+
+
diff --git a/Behavioral/Observer/uml/uml.png b/Behavioral/Observer/uml/uml.png
index 0300bd4..3eff464 100644
Binary files a/Behavioral/Observer/uml/uml.png and b/Behavioral/Observer/uml/uml.png differ
diff --git a/Behavioral/Observer/uml/uml.svg b/Behavioral/Observer/uml/uml.svg
index 09c79c1..44f3c60 100644
--- a/Behavioral/Observer/uml/uml.svg
+++ b/Behavioral/Observer/uml/uml.svg
@@ -1,310 +1,649 @@
-
+