https://github.com/kamranahmedse/design-patterns-for-humans
Factory is an ambiguous term that stands for a function, method or class that supposed to be producing something. Most commonly, factories produce objects. For instance, any of these things may be casually referenced as a “factory”:
Creation method is just a wrapper around a constructor call.
class Number { private $value; public function __construct($value) { $this->value = $value; } public function next() { return new Number ($this->value + 1); } }
class User { private $name, $email, $phone; public function __construct($name, $email, $phone) { $this->name = $name; $this->email = $email; $this->phone = $phone; } public static function load($id) { list($id, $name, $email, $phone) = DB::load_data('users', 'id', 'name', 'email', 'phone'); $user = new User($id, $name, $email, $phone); return $user; } }
A class that has one creation method with a large conditional that based on method parameters chooses which product class to instantiate and then return.
class UserFactory { public static function create($type) { switch ($type) { case 'user': return new User(); case 'customer': return new Customer(); case 'admin': return new Admin(); default: throw new Exception('Wrong user type passed.'); } } }
Definition:
Applicability:
Pros/cons:
- Simplifies adding new products to the program. - x Requires extra subclasses.
Definition: Lets you produce different types and representations of an object using the same building process
Example: Build a house has multiple steps. The pattern organizes the object construction into a set of steps (such as buildWalls
, buildDoor
, etc.) To create an object, you will need to call several building steps in a builder class. The important part here is that you do not need to call all the steps. You can use only the steps necessary for producing a particular configuration of an object.
UML:
Applicability
Definition: Lets you produce new objects by copying existing ones without compromising their internals. Problem: You have an object and want to create a duplicate. How would you do it? First, you need to create a fresh object of the same class. Then you have to go over through all fields of the original object and copy their values to the new object.
Nice! But there is a catch. Not all objects can be copied this way. Some of the objects can have private fields not accessible from the outside. Solution: The Prototype pattern delegates cloning process to objects themselves. Objects that can be cloned are called prototypes.
Applicability
clone
keyword to create an exact copy of an object. To add cloning support to a class, you need to implement a __clone
method.Definition: Allows objects with incompatible interfaces to collaborate.
UML
2 - Existing interface that is supported y the rest of the code 3 - Class that cannot work directly with your code 4 - Adapter: Implements IClientInterface and holds a reference to the service class.
Complexity: 1/3 Popularity: 3/3 Usage examples: The Adapter pattern is pretty common in PHP code. It's very often used in systems based on some legacy code. In such cases, Adapters make legacy code with modern classes.
Definition: Decouple an abstraction from its implementation so that the two can vary independently.
Definition: Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. (Box and product that can contain boxes)
Example: The Composite pattern suggests treating all different Products
and Boxes
through a common interface that has a method getPrice()
. In Products
, it will just return the product's price.. But in a box will go over its content and ask every item its price.
UML:
Definition: Attach new behaviors to objects by placing them inside wrapper objects that contain these behaviors. Problem: You want to add behavior or state to individual objects at run-time. Inheritance is not feasible because it is static and applies to an entire class. Solution: The decorator pattern relies on special objects called decorators (or wrappers). They have the same interface as an object that they suppose to wrap, so the client code will not notice when you hand it a wrapper instead of the original object. All wrappers have a field for storing an instance of an original object. Most wrappers initialize that field with an object passed into their constructor. When you call a decorator's method, it executes the same method in a wrapped object and then adds something to the result. It can also be called before the original method, but that is up to the business logic. You can wrap an object with a decorator, and then wrap the result with another decorator
UML:
Complexity: 2/3 Popularity: 3/3 Usage examples: The Decorator is pretty standard in PHP code, especially in code related to streams.
Definition: Design pattern that lets you provide a simplified interface to a complex system of classes, library or framework.
UML:
Complexity: 1/3 Popularity: 2/3 Usage examples: The Facade pattern is commonly used in PHP applications, where the facade classes simplify the work with complex libraries or APIs.
Definition: Lets you fit more objects into the available amount of RAM by sharing common parts of object state among multiple objects, instead of keeping it in each object. The Flyweight pattern is especially rarely used in PHP applications due to the very nature of the language. A PHP script typically works with a part of the application’s data and never loads all of it into the memory at the same time
Definition: Lets you provide a substitute or placeholder for another object to control access to it. Problem: You need to support resource-hungry objects, and you do not want to instantiate such objects unless and until they are actually requested by the client. While the Proxy pattern is not a frequent guest in most PHP applications, it's still very handy in some special cases. It's irreplaceable when you want to add some additional behaviors to an object of some existing class without changing the client code.
Complexity: Lets you define the skeleton of an algorithm and allow subclasses to redefine certain steps of the algorithm without changing its structure.
Complexity: 1/3 Popularity: 2/3 Usage examples: The Template Method pattern is quite common in PHP frameworks. The pattern simplifies the extension of a default framework's behavior using the class inheritance.
Definition: Define a one-to-many dependency between objects so that when one object changes state (or executes some behaviour), all its dependents are notified and updated automatically. UML:
update
method. The method may have several parameters that allow subscribers receiving some of the event details along the update.
Definition: Encapsulate a request as an object. An object-oriented callback
Problem: Need to issue requests to objects without knowing anything about the operation being requested or the receiver of the request.
Discussion: Command decouples the object that invokes the operation from the one that knows how to perform it. All clients of Command objects treat each object as a "black box" by simply invoking the object's virtual execute()
method whenever the client requires the object's "service".
UML:
Definition: Provide a way to access the elements of an aggregate object (collection, list...) sequentially without exposing its underlying representation. Problem: Need to "abstract" the traversal of wildly different data structures so that algorithms can be defined that are capable of interfacing with each transparently.
UML:
Definition: NullObject is not a GoF design pattern but a schema which appears frequently enough to be considered a pattern. Encapsulate the absence of an object by providing a substitutable alternative that offers suitable default do nothing behavior
Discussion: Methods that return an object or null should instead return an object orNullObject
. NullObject
s simplify boilerplate code such asif (!is_null($obj)) { $obj->callSomething(); }
to just$obj->callSomething();
by eliminating the conditional check in client code.
UML:
AbstractObject
implements default behavior for the interface common to all classes**RealObject**
defines a concrete subclass of AbstractObject whose instances provide useful behavior that Client expects**NullObject**
-
Definition: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. ( An object-oriented state machine)
Discussion:
Its main idea is that a program can be in one of the several states, which follow each other. The number of states and possible transitions between them is predefined and finite. Depending on the current state, the program behaves differently in response to the same events.
State machines are usually implemented with lots of conditional operators, such as if
or switch
, that check current state and perform appropriate behavior.
The biggest limitation of the state machine build with conditionals will show itself if you add some more states and state-dependent behaviors.
Solution: The State pattern suggests to create new classes for all possible states of a context object and to extract the state-related behaviors into these classes.
UML:
switch
operators into objects. Definition: A way of passing a request between a chain of objects. An object-oriented linked list with recursive traversal. Problem: You handle a web request and authoritate users, encrypt data, filter data, add cache. You need to repeat this code in different parts of the applications. Solution: Like many other behavioral design patterns, the Chain of Responsibility relies on transforming behaviors into stand-alone objects. In our case, each check will be moved to a separate class with a single method that runs the check. The method will be able to accept request data through its parameters. The pattern suggests to link these handler objects into a chain. Each handler will get a field for storing a reference to the next handler in the chain. Whenever a handler receives a request, it may pass it to the following handler on the chain. The request would travel along the chain until all handlers had a chance to process it. UML:
Definition: Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from the clients that use it. Purpose: 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). Problem: You have a navigation app and you are implementing routes for walking, car, bike, bus ... Each time a new routing algorithm is added your main class grows a lot. Solution: Big class that does something important in different ways => extract to different classes. The original class (context) will delegate the work to the strategy that the client will pass. UML:
Context stores a reference to a Concrete Strategy object, but works with it through a common _Strategy_interface. Context should expose a setter that allows other objects to replace linked strategy object. Strategy declares the common interface for all strategies. This interface makes concrete strategies interchangeable in Context. Concrete Strategies implement different algorithms, which aim to accomplish the same task in various ways. The Context calls its strategy object each time when it needs to run that task. It does not know, however, in which way the task will be executed. Client know what strategy should be picked depending on the situations. They can configure the Context with a different strategy whenever they want at runtime, using the setter.
Complexity: 1/3 Popularity: 3/3 Usage examples: The Strategy pattern is often used in PHP code, especially when it’s necessary to switch algorithms at runtime. However, the pattern has a strong competitor represented by anonymous functions, supported in PHP since 2009.!!
Complexity: 2/3 Popularity: 2/3 Usage examples: The pure implementation of the Mediator pattern is not as common in PHP. However there are still uses for the Mediator pattern like the event dispatchers of many PHP frameworks or some implementations of MVC controllers.
Complexity: 3/3 Popularity: 1/3 Usage examples: The actual applicability of the Memento pattern in PHP is very questionable. In most cases, you could make a copy of an object's state easier by simply using serialization.
Definition: Lets you produce families of related objects without specifying their concrete classes.
Problem: You are creating a simulator of furniture and you need to combine related products (chair, sofa, coffetable) with variants (IKEA, ArtDeco, Classic)
Solution:
1 - Go over all distinct products and force their variants to follow common interfaces (all chair variants must follow the Chair
interface; all coffee tables must implement the CoffeeTable
interface, etc.)
2 - Create the AbstractFactory
a base interface that declares methods for creating all products that make a product family (i.e. createChair
, createSofa
and createCoffeeTable
). The important thing here is to make these methods to return abstract product types represented by interfaces we extracted previously: Chair
, Sofa
, CoffeeTable
, etc.
3 - Implement concrete factories. IKEAFactory
, will only return IKEAChair
, IKEASofa
and IKEACoffeeTable
objects
4 - Client code has to work with factories and products only through their abstract intThe pattern organizes the object construction into a set of steps (such as buildWalls, buildDoor, etc.) To create an object, you will need to call several building steps in a builder class. The important part here is that you do not need to call all the steps. You can use only the steps necessary for producing a particular configuration of an object.erfaces.
The Abstract Factory is a creational design pattern that allows producing families of related or dependent objects without specifying their concrete classes.
What are the "families of objects"? For instance, take this set of classes: Transport
+ Engine
+ Controls
. There are might be several variants of these:
Car
+ CombustionEngine
+ SteeringWheel
Plane
+ JetEngine
+ Yoke
Applicability:
- When a business logic must work with different variants of products from some product family, but you do not want it to depend on concrete product classes - When a class has multiple Factory Methods
Complexity: 2/3 Popularity: 3/3 Usage examples: The Abstract Factory pattern is pretty common in PHP code. Many frameworks and libraries use it to provide a way to extend and customize their standard components.