This is a collection of known design patterns and some sample code how to implement them in PHP. Every pattern has a small list of examples (most of them from Zend Framework, Symfony2 or Doctrine2).
The problem with patterns is that often people do know them but don’t know when to apply which.
Chapter 1.1 Creational
In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation.
- To create a series of related or dependent objects without specifying their concrete classes.
- A builder is an interface that builds parts of a complex object.
- Sometimes, if the builder has a better knowledge of what it builds, this interface could be an abstract class with default methods
- Factory Method
- The good point over the SimpleFactory is you can subclass it to implement different ways to create objects.
- It means the FactoryMethod class depends on abstractions, not concrete classes. This is the real trick compared to SimpleFactory or StaticFactory.
- The object pool pattern is a software creational design pattern that uses a set of initialized objects kept ready to use – a “pool” – rather than allocating and destroying them on demand.
- However, these benefits are mostly true for objects that are expensive with respect to time, such as database connections, socket connections, threads and large graphics objects like fonts or bitmaps.
- To avoid the cost of creating objects the standard way (new Foo()) and instead create a prototype and clone it.
- Simple Factory
- SimpleFactory is a simple factory pattern.
- It differs from the static factory because it is not static. Therefore, you can have multiple factories, differently parameterized, you can subclass it and you can mock it. It always should be preferred over a static factory!
- THIS IS CONSIDERED TO BE AN ANTI-PATTERN! FOR BETTER TESTABILITY AND MAINTAINABILITY USE DEPENDENCY INJECTION!
- To have only one instance of this object in the application that will handle all calls.
- Static Factory
- Similar to the AbstractFactory, this pattern is used to create a series of related or dependent objects. The difference between this and the abstract factory pattern is that the static factory pattern uses just one static method to create all types of objects it can create. It is usually named factory or build.
Chapter 1.2 Structural
- In Software Engineering, Structural Design Patterns are Design Patterns that ease the design by identifying a simple way to realize relationships between entities.
- Adapter / Wrapper
- An adapter allows classes to work together that normally could not because of incompatible interfaces by providing its interface to clients while using the original interface.
- Decouple an abstraction from its implementation so that the two can vary independently.
- This is used to treat a group of objects the same way as a single instance of the object.
- e.g a form class instance handles all its form elements like a single instance of the form, when
render()is called, it subsequently runs through all its child elements and calls
- Data Mapper
- A Data Mapper is a Data Access Layer that performs bi-directional transfer of data between a persistent data store (often a relational database) and an in-memory data representation (the domain layer).
- The key point of this pattern is, unlike Active Record pattern, the data model follows the Single Responsibility Principle.
- DB Object Relational Mapper (ORM) : Doctrine2 uses DAO named as “EntityRepository”
- Decorators are used to dynamically add new functionality to class instances.
- Dependency Injection
- This is used to implement a loosely coupled architecture in order to get better testable, maintainable and extendable code.
- The primary goal of a Facade Pattern is not to avoid you having to read the manual of a complex API. It’s only a side-effect. The first goal is to reduce coupling and follow the Law of Demeter.
- The best facade has no new and a constructor with interface-type-hinted parameters. If you need the creation of new instances, use a Factory as an argument.
- Fluent Interface
- This is used to write code that is easily readable just like sentences in a natural language like English
- To minimize memory usage, a Flyweight shares as much memory as possible with similar objects. It is needed when a large amount of objects is used that doesn’t differ much in state.
- This is used to interface to anything that is expensive or impossible to duplicate
- This is used to implement a central storage for objects often used throughout the application, is typically implemented using an abstract class with only static methods (or using the Singleton pattern).
- Remember that this introduces global state, which should be avoided at all times! Instead, implement it using Dependency Injection!
Chapter 1.3 Behavioral
- In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication.
- Chain of Responsibilities
- To build a chain of objects to handle a call in a sequential order. If one object cannot handle a call, it delegates the call to the next in the chain and so forth.
- The purpose of this is to encapsulate invocation and decoupling
- We have an Invoker and a Receiver. This pattern uses a “Command” to delegate the method call against the Receiver and presents the same method “execute”. Therefore, the Invoker just knows to call “execute” to process the Command of the client. The Receiver is decoupled from the Invoker.
- The second aspect of this pattern is the undo(), which undoes the method execute(). A command can also be aggregated to combine more complex commands with minimum copy-paste and relying on composition over inheritance.
- To make an object iterable and to make it appear like a collection of objects.
- Standard PHP Library (SPL) defines an interface Iterator which is best suited for this! Often you would want to implement the Countable interface too, to allow count($object) on your iterable object
- This pattern provides an easy way to decouple many components working together. It is a good alternative to Observer IF you have a "central intelligence", like a controller (but not in the sense of the MVC)
- All components (called Colleague) are only coupled to the MediatorInterface and it is a good thing because in OOP, one good friend is better than many. This is the key feature of this pattern.
- It provides the ability to restore an object to it’s previous state (undo via rollback) or to gain access to state of the object, without revealing it’s implementation (i.e., the object is not required to have a function to return the current state).
- The memento pattern is implemented with three objects: the Originator, a Caretaker, and a Memento.
- Memento – an object that contains a concrete unique snapshot of a state of any object or resource: string, number, array, an instance of a class and so on.
- Originator – it is an object that contains the actual state of an external object is strictly specified type.
- Caretaker controls the states history.
- Null Object
NullObjectis not a GoF design pattern but a schema which appears frequently enough to be considered a pattern.
- To implement a publish/subscribe behavior to an object, whenever a “Subject” object changes its state, the attached “Observers” will be notified. It is used to shorten the amount of coupled objects and uses loose coupling instead.
- Builds a clear specification of business rules, where objects can be checked against. The composite specification class has one method called isSatisfiedBy that returns either true or false depending on whether the given object satisfies the specification.
- Encapsulate varying behavior for the same routine based on an object’s state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements.
- The purpose of this pattern is to separate strategies and to enable fast switching between them. Also, this pattern is a good alternative to inheritance (instead of having an abstract class that is extended).
- Template Method
- The idea is to let subclasses of this abstract template “finish” the behavior of an algorithm.
- In other words, this is a skeleton of an algorithm, well-suited for framework libraries. The user has just to implement one method and the superclass does the job.
- It is an easy way to decouple concrete classes and reduce copy-paste, that’s why you’ll find it everywhere.
- The Visitor Pattern lets you outsource operations on objects to other objects. The main reason to do this is to keep a separation of concerns. But classes have to define a contract to allow visitors.
Chapter 1.4 More
- Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
- The Entity–attribute–value (EAV) model is a data model to describe entities where the number of attributes (properties, parameters) that can be used to describe them is potentially vast, but the number that will actually apply to a given entity is relatively modest.