Observer pattern in PHP
Observer pattern is the one I encounter the most. In all object-oriented frameworks I have seen an Observer pattern implemented either in its pure form or by means of the Mediator, also known as event dispatcher. It is one of behavioral patterns therefore it defines the interaction between the objects. It does it in the following way: the Subject keeps the list of Observers and notifies them when some event happens. In order to be notified all observers must implement a particular interface, usually called Observer with single method notify() – that is the only thing that subject requires from its observers. So Subject class gets decoupled from the concrete classes of its Observers that ensures better reusability. Here is a class diagram:
In simple terms when the object of type A (Subject) wants to notify objects of type B, C or D (Concrete Observers) it can do it without knowing what particular classes they represent. The only condition is that Observers must implement the Observer interface containing a single method called notify(). The class A is only aware of the Observer interface and not of classes B, C or D. The subject has to be positive that his observers have the method notify() to call if needed. This need usually comes on some event: a user clicks the interface element, the form construction finishes, the new request appears, the entity is fetched from database (or is about to insert, or get inserted, or is about to update or get updated) and so forth. The Subject can be anything: the form, the form builder, Doctrine framework, Symfony kernel. It can run third-party code plugged in it as an Observer at specific points of its lifecycle (the events).
This allows the subject to send notifications to whatever observer. On the other hand, the observer can listen to events from any subject. Both become decoupled, reusable and separately distributable.
You are welcome to explore my implementation of the Observer pattern here.
As you could see, the Subject uses all its Observers whenever it throws any notification. Whether the Observers interested or not in this particular notification, they are notified anyway. It is often useful when particular event happens to notify only the Observers interested in this event and ignore others. The solution is to turn Observer into EventListener and subscribe them to particular Event of Subject. In this case the code would be similar to :
In the second part, I will show you how to use the event system of Symfony form component to make use of dependent selects.