Документация Symfony для сервисных предприятий объясняет, как разрешить контейнеру сервисов создавать экземпляры сервисов с использованием фабрик, но не объясняет, каков рекомендуемый лучший метод, когда создание не удается, т. е. когда сервис по какой-либо причине недоступен.
Например; представьте себе сервис кэширования памяти Redis. Внутри фабричного класса у вас есть метод, который будет создавать и возвращать клиентский объект Redis;
public function createRedisClient() {
$redis = new \Redis();
$connectionResult = $redis->connect($host, $port);
return $redis;
}
Если сервер Redis временно недоступен, и я хотел бы иметь возможность изящно прибегнуть к другому решению для хранения любых данных, которые у нас есть, в случае возврата к заводским настройкам null
Бросить исключение какого-то конкретного вида или просто не заботиться о доступности?
Вы можете использовать PHP is_object метод:
public function createRedisClient() {
$redis = new \Redis();
$connectionResult = $redis->connect($host, $port);
if (!is_object($redis)) {
return false;
}
return $redis;
}
Возвращаемое значение:
Возвращает ПРАВДА если var объект, ЛОЖЬ в противном случае.
Ссылка : PHP is_object
Если вы хотите использовать «резервное» решение, то лучше всего группировать сервисы такого типа под общим интерфейсом, а не пытаться создавать по одному за раз, как «цепочку ответственности»: первое, что может быть создано, возвращает.
Конечно, в ваших клиентах вы будете использовать интерфейс, так что этот процесс будет совершенно простым для «разработчика клиента».
Лучший способ добиться этого — иметь что-то вроде SessionStorageFactory
(так общий), где вы можете «зарегистрировать» все конкретные заводы (RedisFactory
, …, DefaultSessionStorageFactory
) и попытаться создать экземпляр по одному.
Конечно, недостатком является то, что если вам может понадобиться «расширенный набор» атрибутов (например, host
, port
и т. д.), которые бесполезны для всех заводов, кроме конкретного, где требуется параметр.