Remove "factory" & # 8596; "implementation specific"

I have a "provider factory" that creates a vendor specific implementation. To create a correct implementation, it must, among other parameters, typeId . The problem is that in order to pass the correct typeId to the factory, I need to check and, if necessary, change it. And for this, besides other parameters, I need an instance of a specific provider. What is the problem: the provider has to be a singleton (I really don't want to make it a Singleton with capital S) because it queries the database and caches the result in an internal property.

So my question is, is there a better pattern to use, or another way to achieve something like this?

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


source to share


1 answer


I suggest you embed the ChainOfResponsibility pattern in the ProviderFactory so that you don't have to change the ProviderFactory every time you add a new provider or change the logic. You just need to add the RegisterProvider (IProvider provider) method to add the providers to the chain, and then just go through this chain of providers calling bool: DoProviderSuit (int typeId, out IProvider) of each IProvider.



Hope you catch the idea, good luck!

+1


source







All Articles