Шаблоны проектирования

Шаблоны - это способ описания оптимальных методов и хороших дизайнов проектирования. Они предоставляют универсальные пути решения общих проблем программирования.

Фабрика (Factory)

Шаблон Фабрика позволяет создавать объекты во время работы программы. Этот шаблон называется Фабрикой потому, что он отвечает за производство объекта. Параметризированная фабрика принимает в качестве аргумента имя класса, объект которого создается.

Пример #1 Параметризированный фабричный метод

<?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)

Шаблон проектирования Синглтон применяется в тех ситуациях, когда нужно получить единственный экземпляр класса. Синглтон является одним из четырех("Gang of Four") основных создающих шаблонов.

Синглтон обычно применяется в классах для баз данных, логирования, контроллеров(Front Controller) и объектах, определяющих запросы и ответы(Request и Response).

Пример #2 Пример Синглтона

<?php
class Example
{
    private static 
$instance;
    private 
$count 0;

    private function 
__construct()
    {
    }

    public static function 
singleton()
    {
        if (!isset(
self::$instance)) {
            echo 
'Создание нового экземпляра.';
            
$className __CLASS__;
            
self::$instance = new $className;
        }
        return 
self::$instance;
    }

    public function 
increment()
    {
        return 
$this->count++;
    }

    public function 
__clone()
    {
        
trigger_error('Клонирование запрещено.'E_USER_ERROR);
    }

    public function 
__wakeup()
    {
        
trigger_error('Десериализация запрещена.'E_USER_ERROR);
}

?>

Пример ниже иллюстрирует использование Синглтона

<?php
$singleton 
Example::singleton(); // выведет "Создание нового экземпляра."
echo $singleton->increment(); // 0
echo $singleton->increment(); // 1

$singleton Example::singleton(); // вернет тот же самый экземпляр
echo $singleton->increment(); // 2
echo $singleton->increment(); // 3

// все строки ниже вызывают неисправимую ошибку
$singleton2 = new Example;
$singleton3 = clone $singleton;
$singleton4 unserialize(serialize($singleton));
?>
Внимание

Паттерн Синглтон является одним из наиболее противоречивых паттернов. Критики утверждают, что Синглтоны вводят глобальные состояния при их применении и тесно связывают Синглтон и использующие его классы. Это приводит к скрытой зависимости и неожиданным побочным эффектам, что в свою очередь приводит к коду, который сложнее тестировать и поддерживать.

Критики также утверждаю, что не имеет смысла использовать Синглтон в архитектурах "ничего общего" (Shared Nothing Architecture), таких как PHP, где объекты являются уникальными в пределах запроса и никак иначе. Проще и аккуратнее создавать структуры взаимосвязанных объектов с помощью шаблонов Строителей(Builders) и Фабрики(Factory) за один раз в начале запроса.

Синглтоны также нарушают некоторые из "Жестких" принципов ООП проектирования и Закон Деметры. Синглтоны нельзя сериализовывать. Они не могут быть подклассами (до PHP 5.3) и не будут собираться сборщиком мусора из-за того, что экземпляр хранится в статическом атрибуте Синглтона.


Участник рейтинга Тэглайн 2010