desingpatterns [Docs]

User Tools

Site Tools


desingpatterns

https://github.com/kamranahmedse/design-patterns-for-humans

Design Patterns

Creational

Factory

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”:

  • a function or method that creates program’s GUI;
  • a class that creates users;
  • static method that calls a class constructor in a certain way;
  • one of the creational design patterns.

Creation method

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);
    }
}

Static creation method

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;
    }
}

Simple factory pattern

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.');
        }
    }
}

Factory method pattern

enter image description here

Definition:

  • Define an interface for creating an object (Creator), but let subclasses decide which class to instantiate and what to pass to that classes .
  • Defining a "virtual" constructor.
  • A superclass specifies all standard and generic behavior and then delegates the creation details to subclasses that are supplied by the client.

UML:
enter image description here

  1. Interface Product : Single interface for all objects
  2. Concrete Products
  3. Abstract Creator: Factory method that returns the Product type. The main responsibility of a Creator class usually is some core business logic that works with Products.
    CreateProduct (Factory Method)
  4. Concrete Creators implement or override the base factory method, by creating and returning one of the Concrete Products.

    enter image description here

Applicability:

  • The object needs to be initialized in some specific manner
  • When you want to construct a specific class based on an abstract/interface. If you have an interface defined and determine at execution time which exact implementation of the interface to use (for instance by specifying it in a configuration file).

Pros/cons:

 - Simplifies adding new products to the program.
 - x Requires extra subclasses.

Builder pattern

enter image description here

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:

enter image description here

  1. Builder declares steps required to build a product.
  2. Concrete Builders provide different implementations of the construction steps. Builders can also provide methods for fetching a construction result.
  3. Product is an object created as a result of construction. Builders can produce products that do not belong to the same class hierarchy or interface. It is a key difference between the Builder and other creational patterns.
  4. Director constructs products using a Builder object. Usually, client assigns a builder instance to a director just once via constructor parameters. Then director uses that single builder object for all further construction.

Applicability

  • When you have a "telescopic" constructor.
  • When your code has to create different representations of one product (for example, stone and wooden houses). Construction of the product has similar steps that differ in details. Plus, although the products may be similar, they do not necessary have to have a common base class or interface. Complexity: 2/3 Popularity: 3/3 Usage examples: The Builder pattern is a well-known pattern in PHP world. It is especially useful when you need to create an object with lots of possible configuration options. Doctrine Query Builder Builder pattern: $orderlines []= (new OrderlineBuilder()) ->withProductId($productId) ->withQuantity($qty) ->withPrice($price * (1 + $taxtRate)) ->withColorCode(Colors::codeForName($color)) ->build();

Prototype pattern

enter image description here 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.

UML enter image description here

Applicability

  • When your code should not depend on the concrete classes of objects that you need to copy. For examples, when objects' classes are unknown since you work with them via an interface.
  • When you want to reduce the size of a class hierarchy that consists of similar objects, configured in different ways Complexity: 1/3 Popularity: 2/3 Usage examples: The Prototype pattern is available in PHP out of the box. You can use the clone keyword to create an exact copy of an object. To add cloning support to a class, you need to implement a __clone method.

Structural

Adapter

enter image description here

Definition: Allows objects with incompatible interfaces to collaborate.

UML

enter image description here 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. enter image description here

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.

Bridge

enter image description here

Definition: Decouple an abstraction from its implementation so that the two can vary independently.

Composite

enter image description here

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:

enter image description here

  1. Component declares the common interface for both simple and complex elements of a tree.
  2. Leaf is a basic element of a tree that does not have children. Do most of the real job.
  3. Container (aka Composite) is an element that has children: Leaves or other Containers. Containers do not know the type of their children since they work with them via Component interface. delegate the work to their children, then process and sum-up the results before return it to Client.
  4. Client uses all tree elements only through the Component interface. Complexity: 2/3 Popularity: 3/3 Usage examples: The Composite pattern is commonly used when working with object trees. The simplest example would be applying the pattern to elements of the DOM tree, working with the composite and simple elements of the tree in the same way.

Decorator

enter image description here

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:

enter image description here

  1. Component declares the common interface for both wrappers and wrapped objects.
  2. Concrete Component is a class that contains basic behavior that can be altered by decorators.
  3. Base Decorator contains a field for storing wrapped objects. The field should be declared with a Component type to support both Concrete Components and Decorators. Base decorator delegates all operations to a wrapped object.
  4. Concrete Decorators contain extra behaviors that can be dynamically added to the components. Decorators may execute their behavior either before or after calling the same method in wrapped object. enter image description here

Complexity: 2/3 Popularity: 3/3 Usage examples: The Decorator is pretty standard in PHP code, especially in code related to streams.

Facade

Definition: Design pattern that lets you provide a simplified interface to a complex system of classes, library or framework.

UML:

enter image description here

  1. Facade provides convenient access to a particular part of the subsystem's functionality. It knows where to direct the client request and how to prepare all the moving parts.
  2. Additional facades can be created to divide responsibilities and prevent growing an original facade into yet another complex structure. Additional facades can be used either by Clients or other Facades.
  3. Complex subsystem contains dozens of classes. To make them do something meaningful, you have to know their implementation details, the initialization order and lots of other things.
  4. Client uses Facade instead of calling the Subsystem objects directly.

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.

Flyweigth

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

Proxy

enter image description here

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.

Behavioral

Template Method

Complexity: Lets you define the skeleton of an algorithm and allow subclasses to redefine certain steps of the algorithm without changing its structure.

enter image description here

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.

Observer

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:

enter image description here

  1. Publisher issues events interesting for other objects. These events occur when the publisher changes its state or when it executes some behaviors. Publishers contain a subscription infrastructure that allows new subscribers to join and old subscribers to leave the list. When a new event happens, publisher goes over the list of subscribers and calls their notification method, declared by the Subscriber interface.
  2. Subscriber declares the notification interface. In most cases, it consists of a single update method. The method may have several parameters that allow subscribers receiving some of the event details along the update.
  3. Concrete subscribers implement the notification interface and perform some action in response to the update issued by the Publisher. Subscribers usually need more that just a simple method call to properly handle the update. For this reason, publishers often pass some context data as arguments of the notification method. This might even be a reference to the publisher's object itself.
  4. Client creates publisher and subscriber objects separately and then registers subscribers for publisher updates. Sometimes it is convenient to have direct access from a subscriber's object to a specific publisher. The link is often established via subscriber's constructor. It allows the subscriber to fetch updated state directly from the publisher object upon receiving a notification. Complexity: 2/3 Popularity: 3/3 Usage examples: PHP has several built-in interfaces (SplSubject, SplObserver) that can be used to make your implementations of the Observer pattern compatible with the rest of the PHP code.

Command

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:

enter image description here

  1. Invoker stores a reference to a Command object and uses it when an operation needs to be executed. Invokers are not responsible for creating command objects.
  2. Command declares the common interface for all concrete commands.
  3. Concrete commands implement the actual operations.
  4. Receiver contains business logic or data essential to a particular command.
  5. Client creates and configures Concrete Command objects. Then passes these objects to appropriate Invokers. Applicability When you want to queue, schedule, or execute operations remotely. When you need to be able to undo operations. Complexity: 1/3 Popularity: 3/3 Usage examples: The Command pattern is pretty common in PHP code. It's used for queueing tasks, tracking a history of executed tasks and performing the "undo".
    • A text editor : all events are Command which can be undone, stacked and saved.
    • Symfony2: SF2 Commands that can be run from the CLI are built with just the Command pattern in mind
    • big CLI tools use subcommands to distribute various tasks and pack them in “modules”, each of these can be implemented with the Command pattern (e.g. vagrant)

Iterator

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:

enter image description here

  1. Iterator describes the interface for traversing a collection. Usually, these are methods of getting next and previous elements and method for tracking whether or not iteration is over.
  2. Concrete Iterator implements a specific algorithm for traversing a collection of a particular kind
  3. Collection declares the interface for retrieving iterator from the collection.
  4. Concrete Collection returns new instances of a particular concrete iterator class each time Clients request one. Note that the method's signature returns abstract iterator type. This makes client independent from the concrete classes of iterators.
  5. Clients can work with both collections and iterators via their common interfaces. This way they will not be coupled to the concrete classes. It also allows adding new iterators and interchanging them without modifications to existing code. In general case, clients do not create iterators on their own, but rather get them via Collection objects. Complexity: 2/3 Popularity: 3/3 Usage examples: The pattern is very common in PHP code. Many frameworks and libraries use it to provide a standard way for traversing their collections. The PHP has a built-in (http://php.net/manual/en/language.oop5.iterations.php) interface that can be used for building custom iterators compatible with the rest of the PHP code.
    • to process a file line by line by just running over all lines (which have an object representation) for a file (which of course is an object, too)

Null object

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. NullObjects simplify boilerplate code such asif (!is_null($obj)) { $obj->callSomething(); } to just$obj->callSomething(); by eliminating the conditional check in client code.

UML:

enter image description here

  • 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** -
    • provides an interface identical to AbstractObject's so that a null object can be substituted for a real object
    • implements its interface to do nothing. What exactly it means to do nothing depends on what sort of behavior Client is expecting
    • when there is more than one way to do nothing, more than one NullObject class may be required Usage examples:
  • Symfony2: null logger of profiler
  • Symfony2: null output in Symfony/Console
  • null handler in a Chain of Responsibilities pattern
  • null command in a Command pattern

State

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:

enter image description here

  1. Context stores a reference to a Concrete State object and delegates it all state-related behaviors. Context works with a state via the common State interface. Context must expose a method for passing it a new state object.
  2. State declares the common interface for all Concrete States. It declares methods that should make sense for all states. But each state will provide a different implementation.
  3. Concrete States implement behaviors related to a particular state. Additional base classes may be created to avoid duplication of similar code across multiple states. A state may store the back reference to its context object. This would not only give it the access to context data but also provide a way to initiate state transitions. Both the Context and Concrete States may decide when to initiate a state transition and which would the following state be. To perform the transition, a new state object should be passed to the context. Complexity: 1/3 Popularity: 2/3 Usage examples: The State pattern is occasionally used in PHP for turning large and cumbersome state machines based on switch operators into objects.

Chain of Responsability

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:

enter image description here

  1. Handler declares the common interface for all concrete handlers.
  2. Base Hander is an optional class that contains boilerplate code responsible for building and maintaining a chain of objects. The class may contain a field for storing a reference to a next object in the chain.
  3. Concrete Handlers contain the actual code for processing requests. Upon receiving a request, a handler must decide whether or not to process it, and additionally, whether or not to pass it along the chain.
  4. Client may compose chains just once or do it dynamically, depending on the program's logic. Note that a request could be sent to any handler in the chain, it does not always have to be the first one. Usage examples: The Chain of Responsibility pattern is not very common in PHP, since it requires the program to have chains of objects. Arguably, one of the most famous examples of using this pattern in PHP is HTTP Request Middleware described in PSR-15.
    • logging framework, where each chain element decides autonomously what to do with a log message
    • a Spam filter
    • Caching: first object is an instance of e.g. a Memcached Interface, if that “misses” it delegates the call to the database interface

Strategy

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:

enter image description here

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.

enter image description here

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.!!

Mediator

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.

Memento

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.


Abstract factory pattern

enter image description here

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 CoffeeTableinterface, 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. enter image description here enter image description here

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:

  1. Car + CombustionEngine + SteeringWheel
  2. 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.

desingpatterns.txt · Last modified: 2023/10/31 11:00 by deleteme