BeSmartAnd.Pro

Wzorce projektowe to sprawdzone rozwiązania typowych problemów, z jakimi spotykają się programiści podczas projektowania oprogramowania. Używanie wzorców projektowych może znacznie ułatwić tworzenie skalowalnego, czytelnego i łatwego do utrzymania kodu. W tym artykule omówimy trzy popularne wzorce projektowe: Singleton, Fabryka (Factory) oraz Obserwator (Observer), a także zaprezentujemy ich implementacje w PHP.

Singleton

Wzorzec Singleton zapewnia, że dany obiekt będzie miał tylko jedną instancję w całym programie, i umożliwia globalny dostęp do tej instancji.

Przykład w PHP:

class Singleton {

    private static $instance = null;



    private function __construct() {

        // Prywatny konstruktor, aby zapobiec tworzeniu obiektów.

    }



    public static function getInstance() {

        if (self::$instance === null) {

            self::$instance = new self();

        }

        return self::$instance;

    }



    public function doSomething() {

        echo "Singleton is doing something!";

    }

}



// Użycie Singletona

$singleton = Singleton::getInstance();

$singleton->doSomething();

W powyższym przykładzie metoda `getInstance` zapewnia, że instancja klasy `Singleton` jest tworzona tylko raz. Dzięki prywatnemu konstruktorowi, bezpośrednie tworzenie instancji tej klasy poza metodą `getInstance` jest niemożliwe.

Fabryka (Factory)

Wzorzec Fabryki polega na tworzeniu obiektów bez konieczności określania dokładnej klasy, jaka ma zostać utworzona. Fabryka decyduje, jakiego rodzaju obiekt utworzyć, na podstawie dostarczonych parametrów.

Przykład w PHP:

interface Product {

    public function getType();

}



class ConcreteProductA implements Product {

    public function getType() {

        return "Type A";

    }

}



class ConcreteProductB implements Product {

    public function getType() {

        return "Type B";

    }

}



class Factory {

    public static function createProduct($type) {

        switch ($type) {

            case 'A':

                return new ConcreteProductA();

            case 'B':

                return new ConcreteProductB();

            default:

                throw new Exception("Invalid product type");

        }

    }

}



// Użycie Fabryki

$productA = Factory::createProduct('A');

echo $productA->getType(); // Output: Type A



$productB = Factory::createProduct('B');

echo $productB->getType(); // Output: Type B

Fabryka `Factory` w powyższym przykładzie tworzy obiekty klas `ConcreteProductA` lub `ConcreteProductB` w zależności od przekazanego parametru. Dzięki temu kod, który korzysta z fabryki, nie musi znać szczegółów implementacji konkretnych klas.

Obserwator (Observer)

Wzorzec Obserwatora definiuje zależność jeden-do-wielu między obiektami, tak że kiedy jeden obiekt zmienia stan, wszystkie zależne obiekty są powiadamiane i automatycznie aktualizowane.

Przykład w PHP:

interface Observer {

    public function update($subject);

}



interface Subject {

    public function attach(Observer $observer);

    public function detach(Observer $observer);

    public function notify();

}



class ConcreteSubject implements Subject {

    private $observers = [];

    private $state;



    public function attach(Observer $observer) {

        $this->observers[] = $observer;

    }



    public function detach(Observer $observer) {

        $this->observers = array_filter($this->observers, function($obs) use ($observer) {

            return $obs !== $observer;

        });

    }



    public function notify() {

        foreach ($this->observers as $observer) {

            $observer->update($this);

        }

    }



    public function setState($state) {

        $this->state = $state;

        $this->notify();

    }



    public function getState() {

        return $this->state;

    }

}



class ConcreteObserver implements Observer {

    public function update($subject) {

        echo "Observer: State has changed to " . $subject->getState() . "\n";

    }

}



// Użycie wzorca Obserwatora

$subject = new ConcreteSubject();

$observer1 = new ConcreteObserver();

$observer2 = new ConcreteObserver();



$subject->attach($observer1);

$subject->attach($observer2);



$subject->setState("new state");

W tym przykładzie `ConcreteSubject` utrzymuje listę obserwatorów i powiadamia ich o zmianach stanu za pomocą metody `notify`. `ConcreteObserver` implementuje metodę `update`, która jest wywoływana, gdy stan `ConcreteSubject` ulega zmianie.

Podsumowanie

Wzorce projektowe, takie jak Singleton, Fabryka i Obserwator, są niezwykle przydatne w tworzeniu dobrze zaprojektowanego i skalowalnego oprogramowania. Dzięki nim programiści mogą rozwiązywać typowe problemy projektowe w sposób bardziej elegancki i efektywny. Implementacja tych wzorców w PHP jest stosunkowo prosta, a ich zastosowanie może znacznie poprawić jakość kodu i ułatwić jego utrzymanie.