OBSERVER PATTERN — PHP
You can find the patterns I write in other languages but I am writing the language on the end of the title to inform you which language will be there for examples.
In Observer pattern there are classes which are notified and there is a class which notifies them. For example;
You go into a market and buy a chocolate. When you start ‘the buying action’ you will lose money and you will get the chocolate. So buying action will notify the seperate occurances in the background.
WRITING AN EXAMPLE WITH REGISTER
Let’s write an interface called Subject.
Interfaces are like contracts. Classes which implemet them must have the functions you declared in interfaces. That is it.
interface Subject
{
public function attach(Observer $observer);
public function detach($observer);
public function notify();
}
As you see we have 3 functions in Subject interface. Attach is adding observers in an array, detach is getting rid of them and notify will call handle functions of observers..
And this is Observer Interface;
interface Observer
{
public function handle();
}
If we create a Register class which implements Subject Interface.
Don’t forget when you implement Subject interface you must write the functions in that interface too. So
- attach()
- detach()
- notify()
class Register implements Subject
{
protected $observers = [];
public function attach(Observer $observer)
{
$this->observers[] = $observer;
}
public function detach($index)
{
unset($this->observers[$index]);
}
public function notify()
{
foreach ($this->observers as $observer) {
$observer->handle();
}
}
}
As you see, we declared an observer variable and in attach function we are filling it with observers. By detaching you can remove particular observer and with notify you will trigger all the observers in that particular array.
And for example you want an action when a user registers.
class NotifyAdminHandler implements Observer
{
public function handle()
{
var_dump('Notify Admin');
}
}
Below we create a new register object. And with attach function we are saying that NotifyAdminHandler will be in observer array that will be notified. When we call notify, no matter how many observers are in this array, we will call them with foreach loop and start the handle function.
$register= new Register();
$register->attach(new NotifyAdminHandler());
$register->notify();
If you run it;
string(13) “Notify Admin”
Maybe you have too many observer classes in your basket. We can modify attach function like below so that now we can use arrays for our observers. But when you make it an array, the arguement in attach function will not be an Observer class anymore. So we can get rid of the type decleration Observer in atttach() functions in our interface and in our Register class.
interface Subject
{
public function attach($observable);
And we can control if they are instnaces of observers in the function itself, we will know that nothing tricky goes into our function.
If it is an array on the first place , we will use foreach loop to use attach one by one.
public function attach($observable)
{
if (is_array($observable)) {
foreach ($observable as $observer) {
if (!$observer instanceof Observer) {
throw new Exception;
}
$this->attach($observer);
}
return;
}
$this->observers[] = $observable;
}
And let’s say we have one more observer and we want to use them as an array in subject instance;
class MailHandler implements Observer
{ public function handle()
{
var_dump('Mail something');
}
}
And then we can do;
$register = new Register();
$register->attach([ new NotifyAdminHandler(), new MailHandler() ]);
$register->notify();
So as you see we used an array of Observers inside attach function. Right now what will happen we run this script.
string(13) “Notify Admin”
string(15) “Mail something”
Yesterday I have stumbled upon a Laracast lesson and after that wanted to write about this pattern. I am giving you the link of the site below. If you are into PHP and Laravel, it is a great place.