Question

I have class A that has to to receive a factory BFactory. BFactory creates implementations of B. Each implementation class need different services to be injected.

class B
{
};

class C : public B
{
public:
    C(shared_ptr<ServiceL> serviceL);
};

class D : public B
{
public:
    C(shared_ptr<ServiceM> serviceM);
};

Should i inject into BFactory all the services required by all its implementations or should i use a different design? If i inject all services to BFactory, than BFactory will look the following:

class BFactory
{
public:
    BFactory(shared_ptr<ServiceL> serviceL, shared_ptr<ServiceM> serviceM);

    shared_ptr<B> createInstance(Btype type);

private:
    shared_ptr<ServiceL> _serviceL; 
    shared_ptr<ServiceM> _serviceM
};

BFactory::BFactory(shared_ptr<ServiceL> serviceL, shared_ptr<ServiceM> serviceM) : _serviceL(serviceL), _serviceM(serviceM)
{
}

void BFactory::createInstance(Btype type)
{
    if (type == ...)
    {
        return shared_ptr<B>(new C(_serviceL));
    }
    else if (type == ...)
    {
        return shared_ptr<B>(new D(_serviceM));
    }
}
Was it helpful?

Solution

The approach that you demonstrated, where you pass the dependencies of the products to the factory, is the one that I use. In fact, these are usually the only types of dependencies that I inject into a factory.

A factory object's sole purpose in life is to create products on-demand. To fulfill this purpose, it's the factory's responsibility to ensure products have their required dependencies before releasing them into the wild.

Factories are tightly coupled to the types of its products. They have to be, since they're calling the constructors of the products.

One of the consequences of this tight coupling is that the factory is also coupled with its products' dependencies. Consequently, each dependency of a product is also a dependency of the factory, and should be injected into the factory just like any other dependency.

In fact, this is why we design loose coupling everywhere else in the system. With tight coupling, an object has knowledge of its dependency's dependencies, and their dependencies, ad nauseam. By using a factory, we're able to contain this complexity, and keep it from leaking into the rest of the system.

OTHER TIPS

I would create a ServiceFactory and feed it to the BFactory. Then based on the type, BFactory can request ServiceFactory to create appropriate service in the BFactory::createInstance method, which will be used to create the B instance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top