Должен ли я создавать экземпляры других классов в конструкторе?

Недавно я увидел, что мой коллега создает экземпляры классов в конструкторе, поэтому я начал делать то же самое, например:

class FooBar{ private $model1; private $model2; public function __construct() { $this->model1=new Model1(); $this->model2=new Model2(); } } 

И теперь я начинаю удивляться, может быть, может быть лучше создавать модели везде, где они нужны?

Например, для функции foo() требуется модель 1, а для функции bar() требуется model2, но теперь загружаются обе модели.

Итак, вопрос: это правильный способ создать экземпляр других классов? Или я должен просто создавать их, когда они мне нужны в функции?

Ну, как всегда, ни один размер не подходит для всех ответов.

В большинстве случаев класс FooBar объединяет $model1 и $model2 потому что он нуждается в них для выполнения своей функции. В этом случае мало что может сделать FooBar , если у него нет объектов в этих переменных, поэтому это нужно сделать, чтобы создать их в конструкторе.

Иногда агрегированный объект не требуется для выполнения значительной части функции класса FooBar , а построение этого объекта – дорогостоящая операция. В этом случае имеет смысл только построить его по требованию с помощью кода, например:

 class FooBar { private $model1; private $model2; public function Frob() { $model = $this->getModel1(); $model->frob(); } private function getModel1() { if ($this->model1 === null) { $this->model1 = new Model1; } return $this->model1; } } 

Однако это только иногда . Если для класса FooBar требуется $model1 для половины его операций и $model2 для другой половины, это может указывать на то, что FooBar страдает от случая «давайте бросать все внутри одного класса» и вместо этого следует разделить на два класса.

Я хотел бы, чтобы эти зависимости были введены в конструктор в качестве параметров.

Фактически вы должны загружать их, когда вам это нужно, иначе целая куча моделей, которые не требуются (которые могут иметь свои собственные конструкторы с загрузкой большего количества моделей!), Появятся в памяти каждый раз, когда вам понадобится тривиальная операция.

Не создавайте новую модель, если вы не уверены, что будете использовать ее (например, модели, необходимые для локализации и т. Д.)

Это не точная наука, и вы должны следовать своим инстинктам в том, как организовать код.

Если этот подход становится недоступным или вы хотите его протестировать, инъекция зависимости может прийти на помощь.

Но если вы делаете простые сценарии, а время разработки – важный фактор, то, как вы делаете это сейчас, достаточно.