PHP MİMARİSİ #44: Design Patterns in PHP: Singleton, Factory, Strategy, Observer

Design Patterns in PHP: Singleton, Factory, Strategy, Observer

Design Patterns in PHP: Singleton, Factory, Strategy, Observer

1. Konunun Mimari Önemi ve Temel Çalışma Prensibleri

Design patterns are proven solutions to common software design problems. In PHP, implementing design patterns can lead to cleaner, more maintainable, and scalable code. Among the most frequently used design patterns are Singleton, Factory, Strategy, and Observer.

  • Singleton: Ensures that a class has only one instance and provides a global point of access to it.
  • Factory: Provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created.
  • Strategy: Enables selecting an algorithm at runtime. It defines a family of algorithms, encapsulates each one, and makes them interchangeable.
  • Observer: Defines a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

2. Kurumsal Projelerde Dikkat Edilmesi Gereken En İyi Pratikler (Best Practices)

When implementing design patterns in large-scale projects, consider the following best practices:

  • Understand the context and requirements of the project before applying design patterns.
  • Use design patterns to solve specific problems rather than applying them indiscriminately.
  • Document the usage of design patterns in your codebase for better maintenance.
  • Be cautious of over-engineering; simple solutions are often more effective than complex ones.

3. Gerçek Dünya Senaryolarına Uygun Kod Bloğu Örneği

Below is an example of how to implement the Singleton, Factory, Strategy, and Observer patterns in PHP.

Singleton Pattern


<?php
class Database {
    private static $instance;
    
    private function __construct() {}
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new Database();
        }
        return self::$instance;
    }
}
?>
    

Factory Pattern


<?php
interface Payment {
    public function pay($amount);
}

class CreditCardPayment implements Payment {
    public function pay($amount) {
        echo "Paid $amount using Credit Card.";
    }
}

class PayPalPayment implements Payment {
    public function pay($amount) {
        echo "Paid $amount using PayPal.";
    }
}

class PaymentFactory {
    public static function createPayment($type) {
        if ($type === 'creditcard') {
            return new CreditCardPayment();
        } elseif ($type === 'paypal') {
            return new PayPalPayment();
        }
        throw new Exception("Payment type not supported.");
    }
}
?>
    

Strategy Pattern


<?php
interface ShippingStrategy {
    public function calculate($distance);
}

class StandardShipping implements ShippingStrategy {
    public function calculate($distance) {
        return $distance * 2;
    }
}

class ExpressShipping implements ShippingStrategy {
    public function calculate($distance) {
        return $distance * 5;
    }
}

class ShippingContext {
    private $strategy;
    
    public function setStrategy(ShippingStrategy $strategy) {
        $this->strategy = $strategy;
    }
    
    public function calculateShipping($distance) {
        return $this->strategy->calculate($distance);
    }
}
?>
    

Observer Pattern


<?php
class Subject {
    private $observers = [];
    
    public function attach(Observer $observer) {
        $this->observers[] = $observer;
    }
    
    public function detach(Observer $observer) {
        $key = array_search($observer, $this->observers, true);
        if ($key) {
            unset($this->observers[$key]);
        }
    }
    
    public function notify($message) {
        foreach ($this->observers as $observer) {
            $observer->update($message);
        }
    }
}

interface Observer {
    public function update($message);
}

class ConcreteObserver implements Observer {
    public function update($message) {
        echo "Received message: $message";
    }
}
?>
    

4. Performans Optimizasyonu ve Olası Darboğazlar

While design patterns can improve code quality, they can also introduce performance overheads if not used carefully. Here are some considerations:

  • Singleton pattern can introduce performance issues if the instance creation is resource-intensive.
  • Factory pattern can lead to code bloat if there are too many factory methods or classes.
  • Strategy pattern might introduce overhead due to dynamic method dispatching.
  • Observer pattern can lead to performance issues if there are too many observers or if the notification process is complex.

To optimize performance, consider lazy initialization for Singleton, minimizing factory class proliferation, caching strategies, and optimizing the observer notification process.

NasuhAkay
NasuhAkay

Nasuh Akay, 20 yılı aşkın IT deneyimine sahip; kurumsal teknoloji çözümleri, ERP sistemleri, yazılım geliştirme, veri yönetimi ve dijital dönüşüm alanlarında çalışmalar yürüten bir teknoloji profesyonelidir.

Kariyeri boyunca farklı sektörlerde edindiği deneyimlerini; teknoloji, yazılım, veri mimarisi ve iş süreçlerinin geliştirilmesi üzerine yoğunlaştırmıştır.

Bu blogda ERP çözümleri, SQL Server, yazılım geliştirme, yapay zekâ, dijital dönüşüm ve teknoloji dünyasındaki gelişmeler üzerine bilgi, deneyim ve teknik paylaşımlarını okuyucularla buluşturmaktadır.

Amacı, karmaşık teknik konuları anlaşılır bir dille ele almak, gerçek hayatta karşılaşılan problemlere yönelik uygulanabilir çözümler sunmak ve teknoloji alanındaki bilgi birikimini paylaşmaktır.

Articles: 911

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir