dimanche 11 juillet 2021

Good Use of a Static Factory

I have a class which has a number of dependencies. Currently these are set in the constructor:

class Thing
{
    public function __construct()
    {
        $this->dependencyA = new DependencyA();
        $this->dependencyB = new DependencyB();
        $this->dependencyC = new DependencyC($this);
        $this->dependencyD = new DependencyD($this);
    }        
}

This is badly designed in terms of IoC and DI so I want to redesign this so that my dependencies are present in the constructor.

public class Thing
{
    public function __construct(
        $dependencyA, $dependencyB, $dependencyC, $dependencyD)
    {
        $this->dependencyA = $dependencyA;
        $this->dependencyB = $dependencyB;
        $this->dependencyC = $dependencyC;
        $this->dependencyC->setThing($this);
        $this->dependencyD = $dependencyD;
        $this->dependencyD->setThing($this);
     }
}

This makes things a lot easier to test however I do not want clients to have to instantiate all the dependencies. They are strictly internal classes for the Thing. Would this be a good candidate for a Static Factory as proposed below? This does however change how the dependencies that require Thing as a dependency are to be instantiated (i.e I have to set the dependency via a setter rather than a constructor) which I'm a little uncomfortable with. My proposed solution is below. Are there better approaches?

private class Thing
{
    public function __construct(
        $dependencyA, $dependencyB, $dependencyC, $dependencyD)
    {
        $this->dependencyA = $dependencyA;
        $this->dependencyB = $dependencyB;
        $this->dependencyC = $dependencyC;
        $this->setThing($this);
        $this->dependencyD = $dependencyD;
        $this->setThing($this);
    }

    public static function createThing()
    {
        return new Thing(
            new DependencyA(),
            new DependencyB(),
            new DependencyC(),
            new DependencyD());
}

Aucun commentaire:

Enregistrer un commentaire