Полиморфизм и внедрение зависимостей — слишком много зависимостей

Итак, я прочитал, что если мы видим оператор switch, это признак того, что ему нужен полиморфизм.

Я видел такой пример полиморфизма:

include 'vendor/autoload.php';

$calc = new Calculator();

$calc->setOperands(5, 6);
$calc->setOperation(new Addition);
echo $result = $calc->calculate();

И, конечно, могут быть различные классы, такие как Subtract, Multiply, Root и т. Д.

Теперь допустим, что я хочу использовать этот код в фреймворке Laravel, но это, я думаю, должно применяться к любой фреймворке php.

Пример класса сложения (так же может работать любая другая функция калькулятора)

Class Addition implements Operation {
public function run($num, $current){
return $current + $num;
}

}

Калькулятор:

Class Calculator {

protected $result = 0;
protected $operands = array();
protected $operation;

public function getResult()
{
return $this->result;
}

public function setOperands()
{
$this->operands = func_get_args();
}

public function setOperation(Operation $operation)
{
$this->operation = $operation;
}

public function calculate()
{
foreach ($this->operands as $num) {
echo $num;
if ( ! is_numeric($num)) {
throw new InvalidArgumentException;
}
$this->result = $this->operation->run($num, $this->result);
}

return $this->result;
}}

Я пишу такой класс:

class CalcUser
{
private $calc;

public function __construct(Calculator $calc)
{
$this->calc = $calc;
}

public function index()
{
$this->calc->setOperands(5, 6);
$this->calc->setOperation(new Addition);
$result = $calc->calculate();

// imagine we have long formula to calculate so we add here many functions
// (5+6) * 12 + 21  / 6 + sqrt(4) ...
$this->calc->setOperands($result, 6);
$this->calc->setOperation(new AnyOtherFunction);
echo $result = $calc->calculate();

}

}

И это должно работать, не проверял мой класс CalcUser, просто написал прямо здесь.

Но я вижу одну проблему — там используется ключевое слово новый

А также то, что я прочитал, это:

Признаки непроверяемого кода:

  1. Новые операторы

Единственный раз, когда допустимо создать экземпляр класса внутри
другой класс, когда этот объект является то, что мы называем
объект-значение или простой контейнер с геттерами и сеттерами, которые
не выполняет никакой реальной работы

Хорошо, теперь я могу добавить класс Addition и другие классы в конструктор в качестве параметра, как я сделал с классом калькулятора и новый Оператор будет избегать.

Но тогда есть еще одна вещь:

Слишком много зависимостей

Если вы обнаружите, что конкретный класс требует четыре или более
зависимости, это чаще всего признак того, что ваш
класс просит слишком много

Таким образом, легко получить более 3-х зависимостей, используя только один калькулятор с множеством различных функций.

Так как же мне переформатировать код, чтобы избежать слишком большого количества зависимостей?

0

Решение

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

Так что в основном ваш Calculator класс не имеет зависимостей, ваш CalcUser имеет одну зависимость (Calculator).

Кроме того, я думаю, что вещь о new-keyword / construct заключается в том, что класс не должен вызывать что-либо сам по себе, передавая через него зависимость метода. Это может быть признаком того, что вновь созданный объект является избыточным, если он используется только в экосистеме этого класса. Скажи, что ты никогда не используешь Operation где-нибудь еще в классе, который зависит от него, то есть в этом случае:

class Calculator
{

...

public function newSumOperation()
{
$this->setOperands(func_get_args());
$this->setOperation(new Addition);
}

...
}

class CalcUser
{
...
public function index()
{
$this->calc->newSumOperation(1,2,3);
$result = $this->calc->calculate();

// imagine we have long formula to calculate so we add here many functions
// (5+6) * 12 + 21  / 6 + sqrt(4) ...
$this->newXXXXXOperation(4,3,2);
echo $result = $calc->calculate();

}

}

Итак, как вы видите, в приведенном выше примере вы никогда не используете Addition вне Calculator-учебный класс. Если вы думаете о реальном калькуляторе, вы вводите числа и получаете результат; и между этим калькулятор не продвигает логику сложения чисел во что-то еще, потому что это калькуляторы работа сделать дополнение.

0

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

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

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