Статика нужна тогда, когда член относится к уровню класса, а не объекта. Понят это можно на таком примере, как "прозрачные драйвера". Вот пример из моей практики:
Необходимо реализовать работу с различными кэширующими системами (тот же мемкэш, и др.) так, чтобы замена одной системы на другую не влияло на использующий их код.
Из задачи сразу выделяется:
1) Необходим интерфейс для полиморфности;
2) Необходима фабрика для выбора используемой системы.
Реализуем просто:
abstract class CacheAdapter{
/**
* Метод записывает значение в кэш.
* @abstract
* @param string $key Ключ значения.
* @param mixed $value Значение.
* @param null|integer $time Время кэширования в секундах.
* @return boolean true - если запись успешна, иначе - false.
*/
public abstract function set($key, $value, $time=null);
/**
* Метод возвращает данные из кэша.
* @abstract
* @param string $key Ключ запрашиваемого значения.
* @return string|boolean Ассоциированное с ключем значение или false, если значение не установленно.
*/
public abstract function get($key);
/**
* Метод удаляет данные из кэша.
* @abstract
* @param string $key Ключ удаляемого значения.
* @return boolean true - если удаление выполнено, иначе - false.
*/
public abstract function remove($key);
/**
* Метод устанавливает соединение с кэш-системой.
* @abstract
* @param string $host Адрес сервера, на котором располагается система.
* @param null|integer $port Порт для соединения.
* @return boolean true - если соединение успешно, иначе - false.
*/
public abstract function connect($host, $port=null);
function __set($name, $value){
$this->set($name, $value);
}
function __get($name){
return $this->get($name);
}
function __isset($name){
return $this->get($name) !== false;
}
function __unset($name){
$this->remove($name);
}
}Интерфейс включает методы, доступные всем кэш системам. Теперь нужна фабрика, которая реализуется с использованием статики следующим образом:
class CacheSystem implements \PPHP\tools\patterns\singleton\Singleton{
/**
* Текущий адаптер кэш-системы.
* @var CacheAdapter
*/
protected static $adapter;
/**
* Метод возвращает экземпляр класса драйвера.
* @static
* @throws \PPHP\services\InitializingDataNotFoundException Выбрасывается в случае, если не удалось инициализировать кэш-систему.
* @return CacheAdapter
*/
public static function getInstance(){
if(empty(self::$adapter)){
$conf = \PPHP\services\configuration\Configurator::getInstance();
if(!isset($conf->Cache_Driver) || !isset($conf->Cache_Server)){
throw new \PPHP\services\InitializingDataNotFoundException('Недостаточно данных для инициализации, необходимыми полями являются: Driver, Server');
}
$adapterName = '\PPHP\services\cache\drivers\\' . $conf->Cache_Driver;
$adapter = new $adapterName;
$serverOption = $conf->Cache_Server;
$serverOption = explode(':', $serverOption);
$adapter->connect($serverOption[0], $serverOption[1]);
self::$adapter = $adapter;
}
return self::$adapter;
}
...
}Как можно заметить класс реализует Синглтон интерфес, то есть использующий его код знает только о данном классе и о том, что для получения кэша нужно его инстанциировать через стандартный метод Синглтона getInstance, но реализация метода отличается от стандартной, то есть он не инстанциирует данный класс, а возвращает экземпляр класса-драйвера используемой кэш системы, при этом использующий код не знает об этом:
$cache = \PPHP\services\cache\CacheSystem::getInstance();Вот так мы получаем кэш, но при изменении используемой кэш системы нам не нужно менять никакой код.
Заметьте:
1) Синглтон используется не стандартно - довольно часто многие шаблоны используются нестандартно, это связано с тем, что целью является написание понятного и качественного кода, а не применение шаблонов как таковых;
2) getInstance объявлен как статичный - это связано с тем, что данный метод не может являться объектным по определению.