DEV Community

Cover image for Top 5 Design Patterns Every Software Engineer Should Know
Mhammed Talhaouy
Mhammed Talhaouy

Posted on

5 1

Top 5 Design Patterns Every Software Engineer Should Know

PHP, especially with its modern features like attributes, enums, and readonly properties in PHP, is well-suited for implementing design patterns. Here are five essential patterns every software engineer should know.


1. Singleton Pattern

Ensures a class has only one instance.

final class Config 
{
    private static ?Config $instance = null;

    private function __construct(public readonly array $settings) {}

    public static function getInstance(): Config 
    {
        return self::$instance ??= new Config(['env' => 'production']);
    }
}

// Usage
$config = Config::getInstance();
echo $config->settings['env']; // Output: production
Enter fullscreen mode Exit fullscreen mode

2. Factory Pattern

Centralizes object creation logic.

class DatabaseFactory 
{
    public static function create(string $type): Database 
    {
        return match ($type) {
            'mysql' => new MySQLDatabase(),
            'postgres' => new PostgresDatabase(),
            default => throw new InvalidArgumentException("Unknown database type"),
        };
    }
}

interface Database { public function connect(): void; }
class MySQLDatabase implements Database { public function connect() { echo "MySQL connected"; } }
class PostgresDatabase implements Database { public function connect() { echo "Postgres connected"; } }

// Usage
$db = DatabaseFactory::create('mysql');
$db->connect(); // Output: MySQL connected
Enter fullscreen mode Exit fullscreen mode

3. Observer Pattern

Notifies multiple objects about state changes.

class Event 
{
    private array $listeners = [];

    public function attach(callable $listener): void { $this->listeners[] = $listener; }
    public function trigger(string $data): void { foreach ($this->listeners as $listener) $listener($data); }
}

// Usage
$event = new Event();
$event->attach(fn($data) => print "Listener 1: $data\n");
$event->attach(fn($data) => print "Listener 2: $data\n");

$event->trigger("Event triggered"); 
// Output:
// Listener 1: Event triggered
// Listener 2: Event triggered
Enter fullscreen mode Exit fullscreen mode

4. Decorator Pattern

Dynamically adds behavior to objects.

interface Text { public function render(): string; }

class PlainText implements Text 
{
    public function __construct(private string $text) {}
    public function render(): string { return $this->text; }
}

class BoldText implements Text 
{
    public function __construct(private Text $text) {}
    public function render(): string { return "<b>" . $this->text->render() . "</b>"; }
}

// Usage
$text = new BoldText(new PlainText("Hello, World!"));
echo $text->render(); // Output: <b>Hello, World!</b>
Enter fullscreen mode Exit fullscreen mode

5. Strategy Pattern

Switches between algorithms at runtime.

interface PaymentStrategy { public function pay(float $amount): void; }

class CreditCardPayment implements PaymentStrategy 
{
    public function pay(float $amount): void { echo "Paid $amount with Credit Card\n"; }
}

class PayPalPayment implements PaymentStrategy 
{
    public function pay(float $amount): void { echo "Paid $amount via PayPal\n"; }
}

class PaymentProcessor 
{
    public function __construct(private PaymentStrategy $strategy) {}

    public function execute(float $amount): void 
    {
        $this->strategy->pay($amount);
    }
}

// Usage
$processor = new PaymentProcessor(new PayPalPayment());
$processor->execute(100.00); // Output: Paid 100 via PayPal
Enter fullscreen mode Exit fullscreen mode

These patterns solve real-world problems and are fundamental to writing maintainable and scalable applications.

Which pattern resonates with your current project? Letโ€™s discuss in the comments! ๐Ÿš€

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

Sentry image

See why 4M developers consider Sentry, โ€œnot bad.โ€

Fixing code doesnโ€™t have to be the worst part of your day. Learn how Sentry can help.

Learn more

๐Ÿ‘‹ Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay