diff --git a/readme.md b/readme.md index bacfcaa2..990eb8f7 100644 --- a/readme.md +++ b/readme.md @@ -1794,7 +1794,7 @@ $editor->getContent(); // This is the first sentence. This is second. 😎 Observer -------- Real world example -> A good example would be the job seekers where they subscribe to some job posting site and they are notified whenever there is a matching job opportunity. +> Let’s assume we have a NewsAgency (the subject) that publishes news. Multiple NewsChannels (the observers) are subscribed to this agency, and whenever there is new news, the agency notifies all its channels. In plain words > Defines a dependency between objects so that whenever an object changes its state, all its dependents are notified. @@ -1804,80 +1804,95 @@ Wikipedia says **Programmatic example** -Translating our example from above. First of all we have job seekers that need to be notified for a job posting +Translating our example from above. First of all we have news channels that need to be notified for a news + +- Subject Interface: The subject (NewsAgency) will allow observers (NewsChannels) to subscribe, unsubscribe, and notify them when there’s an update. +- Observer Interface: The observers (NewsChannels) will have a method to get updates from the subject. +```php +interface Subject +{ + public function subscripeChannel(Observer $observer): void; + public function removeChannel(Observer $observer): void; + public function notify(): void; +} + +interface Observer +{ + public function update(string $news): void; +} +``` +Concrete Subject: Implements the subject interface and maintains a list of observers. ```php -class JobPost +class NewsAgency implements Subject { - protected $title; + private array $observers = []; + private string $news; - public function __construct(string $title) + public function subscripeChannel(Observer $observer): void { - $this->title = $title; + $this->observers[] = $observer; } - public function getTitle() + public function removeChannel(Observer $observer): void { - return $this->title; + $this->observers = array_filter($this->observers, function ($obs) use ($observer) { + return $obs !== $observer; + }); } -} - -class JobSeeker implements Observer -{ - protected $name; - public function __construct(string $name) + public function notify(): void { - $this->name = $name; + foreach ($this->observers as $obs) { + $obs->update($this->news); + } } - public function onJobPosted(JobPost $job) + public function setNews(string $news): void { - // Do something with the job posting - echo 'Hi ' . $this->name . '! New job posted: '. $job->getTitle(); + $this->news = $news; + $this->notify(); } } ``` -Then we have our job postings to which the job seekers will subscribe +Concrete Observer: Implements the observer interface and reacts to updates from the subject. ```php -class EmploymentAgency implements Observable +class Channel implements Observer { - protected $observers = []; - - protected function notify(JobPost $jobPosting) - { - foreach ($this->observers as $observer) { - $observer->onJobPosted($jobPosting); - } - } + private string $agencyName; - public function attach(Observer $observer) + public function __construct(string $agencyName) { - $this->observers[] = $observer; + $this->agencyName = $agencyName; } - public function addJob(JobPost $jobPosting) + public function update(string $news): void { - $this->notify($jobPosting); + echo "hi {$this->agencyName}, you have a news: {$news}
"; } } ``` -Then it can be used as + ```php -// Create subscribers -$johnDoe = new JobSeeker('John Doe'); -$janeDoe = new JobSeeker('Jane Doe'); +// create the channels, +$cbc = new Channel("cbc"); +$mbc = new Channel("mbc"); + +// subscripe them into my subject +$newsAgency = new NewsAgency(); +$newsAgency->subscripeChannel($cbc); +$newsAgency->subscripeChannel($mbc); + +// set news +$newsAgency->setNews("this new!!"); -// Create publisher and attach subscribers -$jobPostings = new EmploymentAgency(); -$jobPostings->attach($johnDoe); -$jobPostings->attach($janeDoe); +$newsAgency->removeChannel($cbc); -// Add a new job and see if subscribers get notified -$jobPostings->addJob(new JobPost('Software Engineer')); +$newsAgency->setNews("this the second new!!"); -// Output -// Hi John Doe! New job posted: Software Engineer -// Hi Jane Doe! New job posted: Software Engineer +// expected results: +// hi cbc, you have a news: this new!! +// hi mbc, you have a news: this new!! +// hi mbc, you have a news: this the second new!! ``` 🏃 Visitor