Удалить «фабрику» & lt; — & gt; «конкретную реализацию» зависимость

У меня есть «фабрика провайдеров», которая создает реализацию конкретного провайдера. Для создания правильной реализации необходимо, помимо других параметров, TypeID.
Проблема в том, чтобы пройти правильно TypeID на заводе, мне нужно проверить и, при необходимости, изменить его.
И для этого, помимо других параметров, мне нужен экземпляр конкретного провайдера. Вот в чем проблема — провайдер должен быть одноэлементным (я действительно не хочу делать его одноэлементным с большой буквы S), потому что он запрашивает базу данных и кэширует результат во внутреннем свойстве.

Поэтому мой вопрос — есть ли более подходящий шаблон для использования или другой способ достижения чего-то подобного?

class ProviderFactory
{

public function createProvider($typeId)
{
if ($typeId == 2) {
return new Provider2($arg1, $arg5);
} elseif ($typeId == 4) {
return new Provider4();
} else {
return new ProviderDefault($typeId, $arg1, $arg2, $arg3, $arg4);
}
}
}


interface ProviderInterface
{
public function getCost();
}

class ProviderDefault implements ProviderInterface
{
public function __construct($arg1, $arg2, $arg3, $arg4) {}

public function getCost() { /*implementation*/ }
}

class Provider2 implements ProviderInterface
{
public function __construct($arg1, $arg5) {}

public function getCost() { /*implementation*/ }
}

// this call can be implemented with the following condition
// if ($typeId == 2) {
//      if ($provider2->getCost() !== null)
//          $typeId = 1;
// }
//
$typeId = fixAndValidateTypeId($typeId, new Provider2($arg1, $arg5));


$factory = new ProviderFactory();
$provider = $factory->createProvider($typeId);

3

Решение

Я предлагаю вам реализовать шаблон ChainOfResponsibility в ProviderFactory, чтобы вам не нужно было изменять ProviderFactory каждый раз, когда добавляется новый поставщик или изменяется логика. Вам просто нужно добавить метод RegisterProvider (провайдер IProvider), чтобы добавить провайдеров в цепочку, а затем просто циклически проходить по этой цепочке провайдеров, вызывая bool: DoesProviderSuit (int typeId, out IProvider) каждого IProvider.

Надеюсь, вы поймаете идею, удачи!

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]