Шаблоните за дизайн са начин да се опишат най-добрите практики и методи на проектиране. Те дават гъвкави решения на често срещани в програмирането проблеми.
Шаблонът Фабрика позволява инстанциирането на обекти по време на изпълнение на програмата. Нарича се метод фабрика, защото е отговорен за "производството" на обектите. При параметризираният метод фабрика (Parameterized Factory) името на класа, който трябва да инстанциира се получава като аргумент.
Example #1 Параметризиран метод фабрика (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');
?>
Шаблонът Сек се използва тогава, когато трябва да има точно една инстанция на даден клас. Най-често срещаният пример за това е връзка към база от данни. Реализирането на този шаблон позволява на програмиста да направи тази единствена инстанция лесно достъпна за много други обекти.
Example #2 Сек (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;
?>