Шаблони за дизайн

Шаблоните за дизайн са начин да се опишат най-добрите практики и методи на проектиране. Те дават гъвкави решения на често срещани в програмирането проблеми.

Метод фабрика(Factory Method)

Шаблонът метод фабрика позволява инстанциирането на обекти по време на изпълнение на програмата. Нарича се метод фабрика, защото е отговорен за "производството" на обектите. При параметризираният метод фабрика(Parameterized Factory) името на класа, който трябва да инстанциира се получава като аргумент.

Пример 19-24. Параметризиран метод фабрика(Parameterized Factory Method)

<?php
class Example
{
    // Параметризиран метод фабрика
    public static function factory($type)
    {
        if (include_once 'Drivers/' . $type . '.php') {
            $classname = 'Driver_' . $type;
            return new $classname;
        } else {
            throw new Exception ('Драйверът не е намерен');
        }
    }
}
?>

Дефинирането на този метод в класа позволява на драйверите да бъдат заредени при нужда. Ако класът Example, беше клас за абстракция на бази от данни, зареждането на MySQL и SQLite драйверите щеше да изглежда по следния начин:

<?php
// Зареждане на драйвера за MySQL
$mysql = Example::factory('MySQL');

// Зареждане на драйвера за SQLite
$sqlite = Example::factory('SQLite');
?>

Сек (Singleton)

Шаблонът Сек се използва тогава, когато трябва да има точно една инстанция на даден клас. Най-често срещаният пример за това е връзка към база от данни. Осъществяването на този шаблон позволява на програмиста да направи тази единствена инстанция лесно достъпна за много други обекти.

Пример 19-25. Сек (Singleton) метод

<?php
class Example
{
    // Съдържа единствената инстанция на класа
    private static $instance;
    
    // private конструктор; предотвратява директното инстанцииране на класа
    private function __construct() 
    {
        echo 'I am constructed';
    }

    // Сек (Singleton) метод
    public static function singleton() 
    {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }

        return self::$instance;
    }
    
    // Примерен метод
    public function bark()
    {
        echo 'Woof!';
    }

    // Не позволява на потребителя да клонира инстанцията
    public function __clone()
    {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

}

?>

Това позволява да бъде върната само една единствена инстанция на класа Example.

<?php
// При опитът да се инстанциира този клас ще възникне грешка, тъй като конструктора на класа е private
$test = new Example;

// Това винаги ще връща единствената инстанция на класа
$test = Example::singleton();
$test->bark();

// Това ще върне E_USER_ERROR грешка.
$test_clone = clone $test;

?>