Почему передача объектов с состоянием в конструктор плохая вещь?

Насколько я понимаю, создание экземпляров объектов путем передачи их конструкторам объекта с состоянием является плохой практикой. Возьмите этот код для примера:

class MathValues
{
private $x;

public function __construct($x, $y)
{
$this->x = $x;
$this->y = $y;
}

public function getX()
{
return $this->x;
}

public function getY()
{
return $this->y;
}
}

class MathCalculator
{
private $mathValues;

public function __construct(MathValues $class)
{
$this->mathValues = $class;
}

public function calculateMultiplication()
{
return $this->mathValues->getX() * $this->mathValues->getY();
}
}

$mathValues = new MathValues(2,5);

$mathCalculator = new MathCalculator($mathValues);
$someValue = $mathCalculator->calculateMultiplication();

Сейчас я долгое время был веб-разработчиком, и только недавно я начал разрабатывать ООП-парадигму, следуя (насколько это возможно) принципам SOLID, сервис-ориентированной архитектуре и т. Д. Также в течение некоторого времени я был разработка с использованием фреймворка Symfony2 / 3. Все, что я там вижу (включая контейнер служб Symfony), говорит о том, что конструктор должен использоваться для передачи других служб (экземпляры без сохранения состояния), но я не могу найти, по какому принципу, что вы не должны передавать объект с состоянием в конструктор.

Поэтому мой вопрос такой же, как и в заголовке. Какой принцип говорит, что плохо передавать объект с состоянием в конструктор?

ОБНОВИТЬ

Кажется, мой вопрос не был достаточно ясен, поэтому я обновил свой пример. В этом примере проблемы и решение ясно: каждый раз, когда мне нужно что-то умножить, мне нужно создать 2 экземпляра 2 классов. Вместо этого я мог бы создать один сервис MathCalculator и передать ему 2 аргумента — x и y. Так что мне нужен только 1 экземпляр для всех значений, с которыми я хочу выполнить математические операции, и объект для каждого значения (если даже нужно), с которым мне нужно выполнить математическую операцию.

Не говоря уже о что программирование с сохранением состояния является плохой динамикой, и я верю в разделение неизменных по стоимости объектов и сервисов, которые вообще не имеют состояния.

1

Решение

Прежде всего, как вы уже знаете, так как упомянули об этом в своем обновлении, не стоит продолжать создавать новые экземпляры. MathCalculators каждый раз у тебя разные MathValues для того, чтобы работать на.

Первое, что вам нужно спросить, является ли значения x а также y на самом деле имеют какие-либо предметные, реальные отношения друг с другом в отношении MathCalculator, Если они оба могут быть просто случайными значениями, которые вводит пользователь, то помещать их оба в один класс нехорошо — S из SOLID говорит, что вы должны применять принцип единоличной ответственности или инкапсуляции. Один экземпляр MathValues должно иметь одно значение и y должен стать еще одним примером MathValuesтак что в этом случае MathValues становится избыточным, и вы можете просто использовать набор или список номеров.

Я подозреваю, что вы используете MathValues как Объект передачи данных (DTO)

В противном случае, если x а также y так или иначе связаны, и они принадлежат к одному и тому же классу, например ссылки на геоданные или сетку, то, что вы сделали с MathValues является примером Модель анемичной области анти-паттерн и нарушение Закон Деметры

Вы должны поместить свою бизнес-логику в свою сущность, чтобы придерживаться S из SOLID — ответственность за умение умножать x и y принадлежит MathValuesТаким образом, чтобы выполнить обязанность одиночной ответственности и инкапсуляции, вы должны рефакторинг этого метода в этот класс.

Правда, это спорно, потому что на самом деле СВОЙ MathValues также выглядит как DDD Объект значения в этом случае вы не хотели бы никакой логики там, скорее вы бы агрегировали MathValues в агрегатный класс и поместите метод там вместо. Это решение, которое вы хотели бы принять только позже, когда ваш домен станет более сложным.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]