Skip to content

Design Patterns

This page references the 23 Gang of Four (GoF) design patterns, documenting their theoretical foundations and their application within Phexium's Clean Architecture and CQRS context.

Of the 23 patterns, 16 are implemented in Phexium and 7 are not represented as they are not required by the framework's architectural approach.

Creational Patterns

Creational patterns abstract the instantiation process, making the system independent of how objects are created, composed, and represented.

Abstract Factory

Theory: Provides an interface for creating families of related objects without specifying their concrete classes.

Application Clean Architecture: Each Plugin defines a Port (interface) with multiple interchangeable Adapters depending on the environment. This allows switching implementations (test, development, production) without modifying client code.

Implementation in Phexium:

Component File
Port src/Plugin/Cache/Port/CacheInterface.php
Adapters src/Plugin/Cache/Adapter/InMemoryCache.php, RedisCache.php, FileCache.php
Port src/Plugin/Clock/Port/ClockInterface.php
Adapters src/Plugin/Clock/Adapter/SystemClock.php, FrozenClock.php
Port src/Plugin/SqlDriver/Port/SqlDriverInterface.php
Adapters src/Plugin/SqlDriver/Adapter/SqliteDriver.php, MysqlDriver.php, PostgresqlDriver.php

Learn more on refactoring.guru


Builder

Theory: Separates the construction of a complex object from its representation, allowing the same construction process to create different representations.

Application Clean Architecture: Fluent construction of HTTP responses with optional steps enables readable and flexible response building in controllers.

Implementation in Phexium:

Component File
Builder src/Presentation/ResponseBuilder.php
Methods withHeader(), withStatus(), withHtml(), build()

Learn more on refactoring.guru


Factory Method

Theory: Defines an interface for creating objects, but lets subclasses decide which class to instantiate.

Application Clean Architecture: Value Objects use factory methods (fromString()) to encapsulate validation and guarantee valid instances. ID generators use generate() to produce identifiers.

Implementation in Phexium:

Component File
ID Factory src/Domain/Id/Uuid.php (from())
ID Generators src/Plugin/IdGenerator/Adapter/*Generator.php (generate())
Value Objects app/demo/Library/Domain/Title.php, ISBN.php
Value Objects app/demo/User/Domain/Email.php

Learn more on refactoring.guru


Prototype

Theory: Creates new objects by copying an existing instance (prototype) rather than instantiating a class.

Not implemented

Immutable Value Objects and Entities with identity do not require cloning. Object creation goes through factory methods or constructors, which provide validation guarantees that cloning would bypass.

Learn more on refactoring.guru


Singleton

Theory: Ensures a class has only one instance and provides a global access point to it.

Not implemented

Dependency injection (PHP-DI) manages instance lifecycle. The Singleton pattern is considered an anti-pattern in modern PHP development because it creates global state and complicates testing. The container handles singleton-like behavior when needed.

Learn more on refactoring.guru


Structural Patterns

Structural patterns deal with class and object composition, using inheritance and composition to create larger structures.

Adapter

Theory: Converts the interface of a class into another interface that clients expect.

Application Clean Architecture: Foundation of hexagonal architecture. The Domain layer defines Ports (interfaces), and the Infrastructure layer provides Adapters (implementations). This inverts dependencies and allows the domain to remain independent of infrastructure concerns.

Implementation in Phexium:

Component File
All Ports src/Plugin/*/Port/*Interface.php
All Adapters src/Plugin/*/Adapter/*.php
Domain Port app/demo/Library/Domain/BookRepositoryInterface.php
Adapters app/demo/Library/Infrastructure/SqliteBookRepository.php, InMemoryBookRepository.php

Learn more on refactoring.guru


Bridge

Theory: Decouples an abstraction from its implementation so that the two can vary independently.

Application Clean Architecture: Separates generic SQL operations from DBMS-specific details. The abstract driver defines common behavior while concrete drivers implement database-specific syntax.

Implementation in Phexium:

Component File
Abstraction src/Plugin/SqlDriver/Internal/AbstractSqlDriver.php
Implementations src/Plugin/SqlDriver/Adapter/SqliteDriver.php
Implementations src/Plugin/SqlDriver/Adapter/MysqlDriver.php
Implementations src/Plugin/SqlDriver/Adapter/PostgresqlDriver.php

Learn more on refactoring.guru


Composite

Theory: Composes objects into tree structures to represent part-whole hierarchies. Clients can treat individual objects and compositions uniformly.

Application Clean Architecture: Specifications can be combined (AND, OR, NOT) to build complex queries while maintaining a uniform interface. Each specification, whether simple or composite, implements the same interface.

Implementation in Phexium:

Component File
Interface src/Domain/Specification/SpecificationInterface.php
Composite Base src/Domain/Specification/BinaryAbstract.php (composes left + right)
Leaf Composites src/Domain/Specification/BinaryAndSpecification.php, BinaryOrSpecification.php

Learn more on refactoring.guru


Decorator

Theory: Attaches additional responsibilities to an object dynamically, providing a flexible alternative to subclassing.

Application Clean Architecture: Adds cross-cutting behaviors (transactions, monotonicity) without modifying base implementations. Decorators wrap existing services and enhance them transparently.

Implementation in Phexium:

Component File
Transaction Decorator src/Plugin/CommandBus/Adapter/TransactionalCommandBus.php (wraps CommandBusInterface)
Clock Decorator src/Plugin/Clock/Adapter/MonotonicClock.php (wraps ClockInterface)
Clock Decorator src/Plugin/Clock/Adapter/OffsetClock.php

Learn more on refactoring.guru


Facade

Theory: Provides a unified interface to a set of interfaces in a subsystem, making the subsystem easier to use.

Application Clean Architecture: The Bus components expose a simple dispatch() method that hides handler resolution, routing, and middleware execution. Clients interact with a simple interface while complex orchestration happens behind the scenes.

Implementation in Phexium:

Component File
Command Bus Facade src/Plugin/CommandBus/Adapter/SyncCommandBus.php
Query Bus Facade src/Plugin/QueryBus/Adapter/SyncQueryBus.php
Event Bus Facade src/Plugin/EventBus/Adapter/SyncEventBus.php

Learn more on refactoring.guru


Flyweight

Theory: Reduces memory consumption by sharing common data between multiple objects.

Not implemented

Phexium HTTP requests are stateless and short-lived. Memory optimization through state sharing is not necessary in this context where each request creates fresh object graphs that are garbage collected after the response.

Learn more on refactoring.guru


Proxy

Theory: Provides a surrogate or placeholder for another object to control access to it.

Application Clean Architecture: Interchangeable implementations that are transparent to clients. Null implementations for testing, real implementations for production. The proxy and real subject share the same interface.

Implementation in Phexium:

Component File
Null Logger src/Plugin/Logger/Adapter/NullLogger.php
File Logger src/Plugin/Logger/Adapter/FileLogger.php
Null Cache src/Plugin/Cache/Adapter/NullCache.php

Learn more on refactoring.guru


Behavioral Patterns

Behavioral patterns deal with algorithms and the assignment of responsibilities between objects.

Chain of Responsibility

Theory: Passes a request along a chain of handlers. Each handler decides either to process the request or to pass it to the next handler in the chain.

Application Clean Architecture: PSR-15 middlewares process HTTP requests in a chain (authentication, RBAC, session). Each middleware can process, modify, or reject the request before passing it along.

Implementation in Phexium:

Component File
Session Middleware src/Presentation/Middleware/SessionMiddleware.php
RBAC Middleware app/demo/Shared/Application/Middleware/RbacPermissionMiddleware.php

Learn more on refactoring.guru


Command

Theory: Encapsulates a request as an object, allowing parameterization of clients with different requests, queuing of requests, and logging of operations.

Application Clean Architecture: Core of CQRS. Commands encapsulate write operations, decoupling intent from execution. This enables middleware processing, transaction management, and event dispatching around command handling.

Implementation in Phexium:

Component File
Command Interface src/Application/Command/CommandInterface.php
Handler Interface src/Application/Command/CommandHandlerInterface.php
Bus Interface src/Plugin/CommandBus/Port/CommandBusInterface.php
Example Command app/demo/Library/Application/Command/CreateBookCommand.php

Learn more on refactoring.guru


Interpreter

Theory: Defines a grammar for a language and provides an interpreter to evaluate sentences in that language, typically using an abstract syntax tree.

Not implemented

Phexium does not include a DSL or expression language requiring parsing and interpretation. The Specification pattern (used for query composition) serves a different purpose: it encapsulates business rules rather than parsing grammar. True Interpreter implementations would be needed for template engines, query languages, or expression evaluators.


Iterator

Theory: Provides a way to access elements of a collection sequentially without exposing its underlying representation.

Application Clean Architecture: Domain Collections implement IteratorAggregate for standard traversal. This allows foreach loops and other iteration constructs to work with domain collections.

Implementation in Phexium:

Component File
Collection Interface src/Domain/Collection/CollectionInterface.php (extends IteratorAggregate)
Abstract Collection src/Domain/Collection/AbstractCollection.php
Iterator Trait src/Domain/Collection/Trait/TraitCollectionCore.php (getIterator())

Learn more on refactoring.guru


Mediator

Theory: Defines an object that encapsulates how a set of objects interact, preventing direct references between them.

Not implemented

Inter-module decoupling is achieved through Domain Events (Observer pattern). The Mediator would add complexity without additional benefit in the Phexium context where modules communicate through events rather than direct method calls.

Learn more on refactoring.guru


Memento

Theory: Captures and externalizes an object's internal state so that the object can be restored to this state later.

Not implemented

Phexium uses a classic CRUD approach without state history. Event Sourcing (not implemented) would make this pattern relevant. Current entities are mutable but do not track previous states.

Learn more on refactoring.guru


Observer

Theory: Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

Application Clean Architecture: Domain Events notify listeners of state changes, decoupling modules. A handler can dispatch events without knowing which listeners will react, enabling loose coupling between bounded contexts.

Implementation in Phexium:

Component File
Event Bus Interface src/Plugin/EventBus/Port/EventBusInterface.php
Dispatcher src/Plugin/Dispatcher/Adapter/LeagueDispatcher.php
Example Event app/demo/Library/Domain/Event/BookCreatedEvent.php
Example Listener app/demo/Loan/Application/EventListener/LoanCreatedEventHandler.php

Learn more on refactoring.guru


State

Theory: Allows an object to alter its behavior when its internal state changes. The object will appear to change its class.

Application Clean Architecture: Enums with methods encapsulate state transition rules for entities. The enum itself contains the logic for what operations are valid in each state.

Implementation in Phexium:

Component File
Book Status app/demo/Library/Domain/BookStatus.php (canBeBorrowed(), isAvailable())
Loan Status app/demo/Loan/Domain/LoanStatus.php

Learn more on refactoring.guru


Strategy

Theory: Defines a family of algorithms, encapsulates each one, and makes them interchangeable.

Application Clean Architecture: Plugins allow choosing the algorithm based on context (hashing, caching, persistence). The same interface supports different implementations that can be swapped via dependency injection.

Implementation in Phexium:

Component File
Password Hashers src/Plugin/PasswordHasher/Adapter/ (Argon2id, Bcrypt, Plaintext)
Cache Strategies src/Plugin/Cache/Adapter/ (InMemory, Redis, File)
Presenters app/demo/Library/Presentation/ListBooksHtmlPresenter.php vs ListBooksJsonPresenter.php

Learn more on refactoring.guru


Template Method

Theory: Defines the skeleton of an algorithm in a method, deferring some steps to subclasses.

Application Clean Architecture: Abstract classes define the algorithm structure while concrete classes implement specific details. This ensures consistent behavior while allowing customization.

Implementation in Phexium:

Component File
Abstract Template src/Domain/Specification/BinaryAbstract.php (abstract getSqlTemplate(), evaluateBinary())
Concrete Implementations src/Domain/Specification/BinaryAndSpecification.php, BinaryOrSpecification.php

Learn more on refactoring.guru


Visitor

Theory: Separates an algorithm from the object structure on which it operates, allowing new operations to be added without modifying the classes.

Not implemented

Phexium data structures (Entities, Collections) do not have complex hierarchies requiring this pattern. Operations are defined directly in the relevant classes rather than externalized into visitors.

Learn more on refactoring.guru


Summary

Category Implemented Not Implemented
Creational Abstract Factory, Builder, Factory Method Prototype, Singleton
Structural Adapter, Bridge, Composite, Decorator, Facade, Proxy Flyweight
Behavioral Chain of Responsibility, Command, Iterator, Observer, State, Strategy, Template Method Interpreter, Mediator, Memento, Visitor
Total 16 7