Advanced Design Patterns in PHP: Code Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Design Patterns in PHP: Advanced Level

\n\n

Design patterns are proven solutions to typical problems that arise in software development. At the beginner level, developers learn Singleton, Factory, or Adapter. However, in complex, high-load, or flexible systems in PHP, more powerful and abstract patterns are required. In this article, we will cover four advanced patterns with real code examples in PHP: Strategy, Factory Method, Observer, and State.

\n\n

1. Strategy Pattern

\n\n

Purpose: Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Allows changing the behavior of an object at runtime without modifying its code.

\n\n

Example: A payment processing system. We have several payment methods: credit card, PayPal, cryptocurrency. Each method has its own validation and processing logic.

\n\n
<?php\n\n// Strategy interface\ninterface PaymentStrategy\n{\n    public function pay(float $amount): void;\n    public function validate(): bool;\n}\n\n// Concrete strategies\nclass CreditCardPayment implements PaymentStrategy\n{\n    private string $cardNumber;\n    private string $cvv;\n\n    public function __construct(string $cardNumber, string $cvv)\n    {\n        $this->cardNumber = $cardNumber;\n        $this->cvv = $cvv;\n    }\n\n    public function validate(): bool\n    {\n        // Simple check of card number length\n        return strlen($this->cardNumber) === 16 && strlen($this->cvv) === 3;\n    }\n\n    public function pay(float $amount): void\n    {\n        if (!$this->validate()) {\n            throw new \\InvalidArgumentException("Invalid card data");\n        }\n        echo "Paid {$amount} via credit card {$this->cardNumber}.<br>";\n    }\n}\n\nclass PayPalPayment implements PaymentStrategy\n{\n    private string $email;\n\n    public function __construct(string $email)\n    {\n        $this->email = $email;\n    }\n\n    public function validate(): bool\n    {\n        return filter_var($this->email, FILTER_VALIDATE_EMAIL) !== false;\n    }\n\n    public function pay(float $amount): void\n    {\n        if (!$this->validate()) {\n            throw new \\InvalidArgumentException("Invalid PayPal email");\n        }\n        echo "Paid {$amount} via PayPal ({$this->email}).<br>";\n    }\n}\n\n// Context (client)\nclass OrderProcessor\n{\n    private PaymentStrategy $strategy;\n\n    public function setPaymentStrategy(PaymentStrategy $strategy): void\n    {\n        $this->strategy = $strategy;\n    }\n\n    public function processOrder(float $total): void\n    {\n        if (!isset($this->strategy)) {\n            throw new \\RuntimeException("Payment method not selected");\n        }\n        $this->strategy->pay($total);\n    }\n}\n\n// Usage\n$order = new OrderProcessor();\n$order->setPaymentStrategy(new CreditCardPayment('1234567812345678', '123'));\n$order->processOrder(150.00);\n// Output: Paid 150 via credit card 1234567812345678.\n\n?>
\n\n

Advantages: Easily add new algorithms (new payment methods) without modifying existing code. The code becomes flexible and testable.

\n\n

2. Factory Method Pattern

\n\n

Purpose: Defines an interface for creating an object but allows subclasses to alter the type of object that will be created. This is the base pattern for all creational patterns.

\n\n

Example: Generating different types of reports (PDF, HTML, JSON) depending on user request.

\n\n
<?php\n\n// Abstract product\ninterface Report\n{\n    public function generate(): string;\n}\n\n// Concrete products\nclass PdfReport implements Report\n                

Blogs

Book Recommendations