Consider this PHP code implementing a simple observer pattern. What will it print?
<?php interface Observer { public function update(string $message): void; } class Subject { private array $observers = []; public function attach(Observer $observer): void { $this->observers[] = $observer; } public function notify(string $message): void { foreach ($this->observers as $observer) { $observer->update($message); } } } class ConcreteObserver implements Observer { private string $name; public function __construct(string $name) { $this->name = $name; } public function update(string $message): void { echo $this->name . " received: " . $message . "\n"; } } $subject = new Subject(); $observer1 = new ConcreteObserver("Observer1"); $observer2 = new ConcreteObserver("Observer2"); $subject->attach($observer1); $subject->attach($observer2); $subject->notify("Hello Observers!"); ?>
Think about how many observers are attached and what notify() does.
The Subject has two observers attached. When notify() is called, it calls update() on both observers, so both print their messages.
Choose the best description of the Observer pattern's main purpose.
Think about how objects communicate changes in state.
The Observer pattern lets one object (subject) notify many other objects (observers) automatically when its state changes.
Look at this PHP code snippet. It causes a fatal error. What is the cause?
<?php interface Observer { public function update(string $message): void; } class Subject { private array $observers = []; public function attach(Observer $observer): void { $this->observers[] = $observer; } public function notify(string $message): void { foreach ($this->observers as $observer) { $observer->update($message); } } } class ConcreteObserver { private string $name; public function __construct(string $name) { $this->name = $name; } public function update(string $message): void { echo $this->name . " received: " . $message . "\n"; } } $subject = new Subject(); $observer = new ConcreteObserver("Obs1"); $subject->attach($observer); $subject->notify("Test"); ?>
Check if the observer class matches the interface type hint.
The Subject expects objects implementing Observer interface. ConcreteObserver does not declare it implements Observer, so PHP throws a fatal error when attaching.
We want to add a detach method to remove an observer from the Subject's list. Which option correctly implements this?
<?php class Subject { private array $observers = []; public function attach(Observer $observer): void { $this->observers[] = $observer; } // Implement detach method here } ?>
Use strict comparison and remove only the matching observer.
Option A uses strict comparison and unsets the exact observer. Option A uses loose comparison which can cause issues. Option A returns a filtered array but does not reindex keys, which can cause problems. Option A clears all observers, which is incorrect.
Given this PHP code, how many observers will receive the notification?
<?php interface Observer { public function update(string $msg): void; } class Subject { private array $observers = []; public function attach(Observer $observer): void { $this->observers[] = $observer; } public function detach(Observer $observer): void { $index = array_search($observer, $this->observers, true); if ($index !== false) { unset($this->observers[$index]); } } public function notify(string $msg): void { foreach ($this->observers as $observer) { $observer->update($msg); } } } class ConcreteObserver implements Observer { private string $id; public function __construct(string $id) { $this->id = $id; } public function update(string $msg): void { echo "Observer {$this->id} got: {$msg}\n"; } } $subject = new Subject(); $obs1 = new ConcreteObserver("1"); $obs2 = new ConcreteObserver("2"); $obs3 = new ConcreteObserver("3"); $subject->attach($obs1); $subject->attach($obs2); $subject->attach($obs3); $subject->detach($obs2); $subject->attach($obs2); $subject->detach($obs1); $subject->notify("Update!"); ?>
Track attach and detach calls carefully.
Initially, obs1, obs2, obs3 attached (3 observers). Then obs2 detached (2 left). Then obs2 attached again (3 observers). Then obs1 detached (2 left). The final observers are obs3 and obs2. Because detach uses unset without reindexing, the array keys are not continuous but the foreach still iterates all attached observers. However, obs1 is removed, so only obs2 and obs3 receive the notification.