Today we are going to talk about design patterns in web development, more precisely – in PHP. Experienced developers are probably familiar with this, but this article will be extremely useful for all novice developers. So, what is it – design patterns? Design Patterns aren’t analysis patterns, they are not descriptions of common structures like linked lists, nor are they particular application or framework designs. In fact, design patterns are “descriptions of communicating objects and classes that are customized to solve a general design problem in a particular context.” In other words, Design patterns provide a generic reusable solution to the programming problems that we encounter every day. Design patterns are not ready classes or libraries, that can be simply applied to your system, this is not a concrete solution that can be converted in to source code, design patterns are much more than that. They are patterns, or templates, that can be implemented to solve a problem in different particular situations.
Design patterns help to speed up the development, as the templates are proven and from the developer’s position, only implementation is required. Design patterns not only make software development faster, but also encapsulate big ideas in a simpler way. Also, be careful not to use them in wrong places in order to avoid unpleasant situations. In addition to the theory, we also give you the most abstract and simple examples of design patterns.
“Each pattern describes a problem which occurs over and over again … and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without doing it the same way twice.” – Christopher Alexander
By now there are 23 different known design patterns, and they can be separated into three categories by purpose:
Creational Patterns: used to construct objects such that they can be decoupled from their implementing system
Structural Patterns: used to form large object structures between many disparate objects
Behavioral Patterns: used to manage algorithms, relationships, and responsibilities between objects
Complete list of design patterns you can find below:
Purpose
Design Pattern
Aspect(s) that can vary
Creational
Abstract Factory
families of product objects
Builder
how a composite object gets created
Factory Method
subclass of object that is instantiated
Prototype
class of object that is instantiated
Singleton
the sole instance of a class
Structural
Adapter
interface to an object
Bridge
implementation of an object
Composite
structure and composition of an object
Decorator
responsibilities of an object without subclassing
Facade
interface to a subsystem
Flyweight
storage costs of objects
Proxy
how an object is accessed; its location
Behavioral
Chain of Responsibility
object that can fulfill a request
Command
when and how a request is fulfilled
Interpreter
grammar and interpretation of a language
Iterator
how an aggregate’s elements are accessed, traversed
Mediator
how and which objects interact with each other
Memento
what private information is stored outside an object, and when
Observer
number of objects that depend on another object; how the dependent objects stay up to date
State
states of an object
Strategy
an algorithm
Template Method
steps of an algorithm
Visitor
operations that can be applied to object(s) without changing their class(es)
And now, we can start overview some of the listed patterns
Singleton
This is one of the most popular patterns. When developing web applications, it often makes sense conceptually and architecturally to allow access to only one instance of a particular class (during runtime). The singleton pattern enables us to do this. Example:
Multiton
Maybe someone will want to use a variety of singletons in your project:
Strategy
The strategy pattern is based on algorithms. You encapsulate specific families of algorithms allowing the client class responsible for instantiating a particular algorithm to have no knowledge of the actual implementation. Example:
Decorator
This pattern allows us to add new or additional behavior to an object during runtime, depending on the situation. Example:
Registry
This pattern is a bit unusual from the overall list, because it is not a Creational pattern. Well, register – it is hash, and you access to data through the static methods:
Factory
This is another very known pattern. It acts exactly as it sounds: this is class that does as the real factory of object instances. In other words, assume that we know that there are factories that produce some kind of a product. We do not care how a factory makes this product, but we know that any factory has one universal way to ask for it:
Abstract Factory
There are situations when we have some of the same type of factories and we want to encapsulate the logic of choice, what of the factories use to a given task. This pattern cames to the rescue:
Observer
An object is made observable by adding a method that allows another object, the observer to get registered. If the observable object gets changed, it sends a message to the objects which are registered as observers:
Adapter
This pattern allows you to repurpose a class with a different interface, allowing it to be used by a system which uses different calling methods:
Lazy Initialization
Here is another interesting situation. Imagine that you have a factory, but you do not know what part of its functionality you need, and what – no. In such cases, the necessary operations are performed only if they are needed and only once:
Chain of responsibility
The pattern also has another name – Chain of Command. It follows a chain of command with a series of handlers. The message (query) runs through a series of these handlers and at each junction it is regulated whether the handler can handle the query or not. The process stops the moment a handler can handle the request:
Object pool
Object pool – is a hash, which can be stacked to initialize an object and get them out if needed:
Prototype
Sometime, some objects should be initialized multiple times. It makes sense to save on their initialization, especially if initialization requires time and resources. Prototype – a pre-initialized and saved object. If necessary, it could be cloned:
Builder
This template is used when we want to encapsulate the creation of a complex object:
You may consider to unlock an additional table (bonus)