Peter
Peter

Reputation: 9113

Which method is more efficient in constructing classes?

For each of a bunch of records from my database I instantiate a class. Inside that class I call another class.

Example

$records = array(...);
foreach ($records as $record) {
    $a = new A();
    $data = $a->doSomething($record);
}

class A {
    protected $b;
    public function __construct()
    {
        $this->b = new B();
    }

    public function doSomething($param)
    {
        return $this->b->doSomething($param);
    }
}

The above code is the way I'm currently doing it. However I was wondering if the below would be better:

$records = array(...);
$b = new B();
foreach ($records as $record) {
    $a = new A($b);
    $data = $a->doSomething($record);
}

class A {
    protected $b;
    public function __construct($b)
    {
        $this->b = $b;
    }

    public function doSomething($param)
    {
        return $this->b->doSomething($param);
    }
}

What I would like to know, is if this is efficient at all, which of those options is better and if there are any other solutions that are even better.

Upvotes: 0

Views: 58

Answers (1)

Dan
Dan

Reputation: 10538

Disclaimer: not a PHP dev, but I understand OOP enough to answer this question with...

Option 2 is better.

This is not really a question of efficiency but of a best practice called dependency injection.

With Option 2, A declares it needs a $b to create itself. This gives you the benefit of being able to swap out the instance of $b with whatever you want wherever you instantiate A, and it also makes the code more maintainable by making the requirements of each piece of code more clear. This is great because A doesn't care if B works or not in order for A to work. It just treats the injected class.. which may or may not be B - as a black box. It is loosely-coupled and only depends on the interface of B, rather than the implementation.

With Option 1, you instantiate B within the class. This works fine... until you want to test your code. Or change B at runtime. And then it becomes horribly brittle. Because every single time you want to change A you now have to change B. This means that A is now tightly-coupled to B, which essentially means that for A to work, it also depends on B working - this is not very maintainable because your application essentially becomes a house of cards.

TLDR - Go with option 2, always. It's not a matter of efficiency but maintainability.

Upvotes: 3

Related Questions