Просмотр поста

.
Delphinum
Локатор сервисов
Локация сервисов это по сути аналог шаблона Singleton, но более гибкий и "кошерный". Представим ситуацию: вам необходимо в вашем приложении работать с несколькими таблицами в БД, а так же иметь доступ к конфигурации приложения. Все эти ресурсы, как правило, являются глобально-доступными. Другими словами любой части вашего приложения может потребоваться к ним доступ. С другой стороны, возможно, эти ресурсы необходимо предварительно настроить, прежде чем использовать (к примеру подключиться к БД). Эти задачи как раз решает Bricks.ServiceLocator.

Локатор служб отличается от Singleton тем, что его и все зависимые от него части приложения проще тестировать. Так же этот механизм позволяет полиморфно заменять один ресурс другим, незаметно для системы. К примеру для доступа к БД использовался класс на базе mysqli, но вы решили перейти на PDO. С использованием локатора служб вам потребуется только заменить ресурс доступа к базе, а не "шерстить" весь проект.

Предлагаемый мной пакет очень прост. По сути это ассоциативный массив, которому передаются доступные приложению службы. Рассмотрим пример:

use Bricks\ServiceLocator\Manager;

$locator = new Manager;
$locator->set('config', include('conf/global.conf.php'));
...
$config = $locator->get('config');


В примере демонстрируется работа методов set и get. Первый позволяет зарегистрировать службу под данным именем (в примере это имя config), а второй предоставляет службу по требованию.

Другим достоинством, о котором я уже упоминал ранее, является возможность регистрации фабрик. Фабрика это некоторая функция или метод класса, который будет вызван при обращении к методу get локатора и должен будет сформировать и вернуть требуемый сервис.

Пример:

use Bricks\ServiceLocator\Manager;

$locator = new Manager;
$locator->factory('userTable', function(Manager $locator){
  $conf = $locator->get('config');
  return new PDO('mysql:dbname=user', $conf['db']['user'], $conf['db']['pass']);
});
...
$userTable = $locator->get('userTable');


Здесь фабрика используется для инициализации подключения к базе данных. Важно отметить, что при каждом обращении к этой фабрике, метод будет вызываться заново. На деле это означает, что мы получим несколько подключений к одной и той же таблице. Чтобы этого избежать, достаточно передать true в качестве четвертого параметра метода factory:

use Bricks\ServiceLocator\Manager;

$locator = new Manager;
$locator->factory('userTable', function(Manager $locator){
  $conf = $locator->get('config');
  return new PDO('mysql:dbname=user', $conf['db']['user'], $conf['db']['pass']);
}, null, true);
...
$userTable = $locator->get('userTable');
var_dump($userTable === $locator->get('userTable')); // true


Архив с примером.