Конструктор является частным. Класс Singleton представляет собой одну из ситуаций, когда имеет смысл использовать частный конструктор. Частный конструктор не позволяет пользователям непосредственно реализовывать класс. Для этого они должны использовать метод getlnstance. Попытка реализовать класс с помощью оператора $obj = new Singleton приведет к фатальной ошибке, так как из глобального диапазона нельзя вызывать частный конструктор.
Одним из реальных примеров использования класса Singleton является класс конфигурации, который представляет собой оболочку для настроек приложения. В листинге 29.1 приведен простой пример. Благодаря типовому проекту Singleton в памяти никогда не будет больше одной копии конфигурационного файла. Любые изменения в конфигурации сохраняются автоматически.
Листинг 29.1. Настройка проекта Singleton
<?php /*
** конфигурационный файл singleton
*/
class Configuration class Singleton {
static private $instance = NULL; private function __construct()
{
...по мере необходимости провести инициализациюTM
}
static public function getInstance()
{
if (self::$instance == NULL)
{
self::$instance = new Singleton();
}
return self::$instance;
}
. class logic goes here .
} {
static private $instance = NULL; private $ini_settings; private $updated = FALSE;
const INI_FILENAME = "/tmp/corephp.ini"; private function __construct()
{
if(file_exists(self::INI_FILENAME))
{
$this->ini_settings = parse_ini_file(self::INI_FILENAME);
}
}
private function __destruct()
{
//если конфигурация не претерпела изменения, //то нет необходимости менять ее на диске if(!$this->updated)
{
return;
}
// переписать в файл INI версию из памяти $fp = fopen(self::INI_FILENAME, "w");
if(!$fp)
{
return;
}
foreach ($this->ini_settings as $key => $value)
{
fputs($fp, "$key = "$value"n");
}
fclose($fp);
}
public function getInstance()
{
if(self::$instance == NULL)
{
self::$instance = new Configuration();
}
return self::$instance;
}
public function get($name)
{
if(isset($this->ini_settings[$name]))
{
return $this->ini_settings[$name];
}
else
{
return(NULL);
}
}
public function set($name, $value)
{
//модифицировать только в случае отличия от //того, что есть
if(!isset($this->ini_settings[$name]) OR
($this->ini_settings[$name] != $value))
{
$this->ini_settings[$name] = $value; $this->updated = TRUE;
}
}
}
//Протестировать класс
$config = Configuration::getInstance(); $config->set("username", "leon"); $config->set("password", "secret"); print($config->get("username"));
?>
29.3. Проект Factory
Проект Factory представляет собой типовой проект, предназначенный для разделения реализации объектов от прикладного кода, использующего их в своей работе. Например, можно использовать различные типы объектов в зависимости от ситуации. Если существуют два визуализирующих класса, HtmlRenderer и WmlRenderer, и необходимо прозрачным образом использовать необходимый класс в зависимости от подключенного клиента, то лучше всего воспользоваться типовым проектом Factory.
Существует множество различных вариантов типового проекта Factory. На рис. 29.2 показан простейший вариант, в котором используются глобальные функции.
Метод Factory не принимает никаких аргументов, но во многих ситуациях может потребоваться передать информацию этому методу, чтобы он определил, какой тип объекта необходимо реализовать. Ничто в типовом проекте не препятствует передать аргументы конструктору в типовом проекте Factory.
Довольно популярным случаем при реализации метода Factory является реализация преобразующего кода, принимающего двухмерный трансформированный поток и преобразующего его в объекты.
Каким образом можно создать обобщенный код с возможностью реализовать объект любого типа, который может встретиться в потоке? Что если необходимо задать конструктору различные аргументы, зависящие от типа объекта, который реализуется? Реализация такого класса представлена в листинге 29.2.
Листинг 29.2. Зарегистрированные классы для типового проекта Factory
<?php
class Factory
{
private $registeredClasses = array(); static private $instance = NULL; private function __construct() {} static function getInstance()
{
if(self::$instance == NULL)
{
self::$instance = new Factory();
}
return self::$instance;
}
function registerClass($id, $creator_func)
{
$this->registeredClasses[$id] = $creator_func;
}
function createObject($id, $args)
{
if(!isset($this->registeredClasses[$id]))
{
return(NULL);
}
return($this->registeredClasses[$id]($args));
}
}
class MyClass
{
private $created;
public function __construct()
{
$created = time();
}
public function getCreated()
{
return($this->created);
}
}
function MyClassCreator()
{
return(new MyClass());
}
$factory = Factory::getInstance(); $factory->registerClass(1234, "MyClassCreator"); $instance = $factory->createObject(1234, array());
?>
Читатель, знакомый со всеми нюансами синтаксиса PHP, знает, что существует простейший способ это сделать. В листинге 29.2 продемонстрирован более объектно-ориентированный метод решения проблемы, который был реализован на других языках. Он также имеет определенную гибкость, позволяющую реализовать дополнительную логику при создании (возможно, отправляя определенную информацию конструктору). На практике точнее будет сказать, что PHP имеет встроенную поддержку для метода Factory, реализуемую простым оператором $object = new $classname.
ТОП-10 популярных
Для работы с вещественными числами в MySQL предусмотрено три типа данных - это типы FLOAT, DOUBLE, DECIMAL. Числовой тип FLOAT...
БОЛЬШЕ БОЛЬШИХ LCD-мониторов
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Больше больших LCD-мониторов
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
НОУТБУК с блестящим экраном
Eсли выпустившая ноутбук фирма предлагает его в качестве «замены настольному ПК», то это должно подразумевать под собой нечто большее, чем...
Eсли выпустившая ноутбук фирма предлагает его в качестве «замены настольному ПК», то это должно подразумевать под собой нечто большее, чем...
Иди и пиши. TravelMate C100
Планшетный компьютер платформы Tablet PC обязан в первую очередь быть легким, способным достаточно долго работать без подзарядки батарей. Эти требования...
Планшетный компьютер платформы Tablet PC обязан в первую очередь быть легким, способным достаточно долго работать без подзарядки батарей. Эти требования...
Магнито-оптический дисковод DynaMO
Cейчас, когда традиционные флоппи-дисководы на долгие годы замерли в своем развитии, поиск альтернативных носителей продолжается, и ситуация, казалось бы, разрешилась...
Cейчас, когда традиционные флоппи-дисководы на долгие годы замерли в своем развитии, поиск альтернативных носителей продолжается, и ситуация, казалось бы, разрешилась...
Компьютер для гурманов.«Эксимер ДМ»
Российская компания «Эксимер ДМ», известная как производитель настольных компьютеров, рабочих станций, серверов и ноутбуков, выступила техническим спонсором проведения торжеств, посвященных...
Российская компания «Эксимер ДМ», известная как производитель настольных компьютеров, рабочих станций, серверов и ноутбуков, выступила техническим спонсором проведения торжеств, посвященных...
Для длинных строк, т.е. строк длиннее 255 символов, в MySQL предусмотрены типы BLOB (Binary Large Object, большой двоичный объект) и...
В дополнение к календарным типам, предназначенным для хранения даты и времени отдельно, MySQL также поддерживает гибридные типы данных DATETIME и...
Вообще, к изменению настроек сервера прибегают очень редко. В MySQL программа заранее настроена так, чтобы соответствовать самым распространенным и основным...
PHP. Типовые проекты. Часть Третья.
23-07-2015
<< Предыдущая статья | Следующая статья >> |
PHP. Типовые проекты. Часть Вторая. | PHP. Типовые проекты. Часть Четвёртая. |