Design patterns overview
In modern application development the need to know design patterns emerges as the need to provide more elegant solutions to domain problems.
Design Patterns Types
There are three main design pattern catogories:
1. Structural – they are organizing different classes and objects to provide new functionality and form larger structures.
Structural design patterns are Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Private Class Data and Proxy.
2. Creational – about class instantiation or object creation.
Object-creation patterns use delegation effectively to get the job done.
Class-creational patterns and object-creational patterns. They use inheritance effectively in the instantiation process.
Creational design patterns are Factory Method, Abstract Factory, Builder, Singleton, Object Pool and Prototype.
3. Behavioral – about identifying common communication patterns between objects and realize these patterns.
Behavioral patterns are Chain of responsibility, Iterator, Observer, Visitor, Mediator, Command, Interpreter, Memento, Null Object, State, Strategy, Template method.
Design patterns examples
Builder Design Pattern
Let’s examine some examples of commonly used design patterns in practical life.
Imagine we have a Subway sandwich as model, and each sandwich has its price. There are several sandwich types, as well as combined dressings and additional food perks for them.
If we want to reproduce the domain model, then we would do something like that:
SubOfTheDayWithOlives , SubOfTheDayWithTomatoes, etc. This will hugely increase the domain object complexity, and thus decorator comes in hand.
Decorator wraps the existing class and provides it with the same functionality, but it “decorates” the objects with the additional perks, and when all finished, it calls the sandwihch’s getCost() method which uses delegation instead of inheritance to calculate the price.
More information on this implementation you can find in geeks for geeks site here:
https://www.geeksforgeeks.org/decorator-pattern/
We vastly consume builder design pattern when in need of building forms in the standard frameworks, which provide us with prebuilt factories.
A short example of a symfony build form could be:
/** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('educationType', 'choice', array( 'choices' => array( 'uniEduTypeGov' => 'Government paid’, 'uniEduTypePaid' => 'paid education' ), 'label' => 'Education Type, )) ->add('oksType', 'choice', array( 'choices' => array( 'uniOksBachelor' => 'Bachelor', 'uniOksMaster' => 'Master' ), 'label' => 'Education Grade', )) ->add('sedSchoolName', 'text', array( 'label' => 'School name', 'required' => true )) ->add('uniCountry', 'entity', array( 'class' => 'App\Bundle\Entity\Country', 'property' => 'name', // 'data' => '9', 'label' => 'Country', 'required' => true )) ->add('uniCity', 'entity', array( 'class' => 'App\Bundle\Entity\City', 'property' => 'name', 'data' => '9', 'label' => 'City, 'required' => true )) ->add('sedDiplomaRegNo', 'text', array( 'label' => 'secondary school diploma number’, 'required' => true )) ->add('inform', 'choice', array( 'label' => 'I am informed about the terms and conditions', 'required' => true )); }
More information on the builder pattern can be found here:
https://www.geeksforgeeks.org/builder-design-pattern/
More information on symphony builder objects can be found here:
https://symfony.com/doc/current/forms.html
The builder allows us to assemble a complex form object, by instantiating within it other field objects based on their field type (integer, text, choice, entity – that’s when we have to attach specific field to other domain objects and ensure the domain objects are properly validated and present).
Publish/subscribe and Observer design patterns
Another commonly used design pattern is the publish/subscribe design pattern. This design pattern is referred to when there is a pool of domain objects which have to register for specific events (publishers), and then there are the subscribers, each of which is ‘subscribed’ to a bunch of publishers. Based on the event occurred, each subscriber is initially subscribed to the events it has to listen to. When the event occurs the publisher notifies the subscribers through its notify() method that the event has occurred.
Observer pattern, on the other side gives the classes a more decoupled way to implement the same behavior. You may think of the Observer design pattern every time when some data is delegated to a message queue. All queue listeners implement the observer pattern, and the classes using this pattern are agnostic to the classes and events which provided the data in the message queue.
A nice explanation of the difference between publish/subscribe and observer design pattern can be found here.
https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c