У этого куска кода есть несколько проблем, которые, кстати, могут быть сокращены следующим образом:
public List<Money> getMoneyByPersons() {
return persons.size() == 1 ?
moneyService.getMoneyIfHasOnePerson() :
moneyService.getMoney();
}
Непонятно, почему один человек является особым случаем. Я предполагаю, что есть определенное бизнес-правило, которое говорит, что получение денег от одного человека радикально отличается от получения денег от нескольких человек. Тем не менее, я должен пойти и посмотреть внутрь обоих, getMoneyIfHasOnePerson
и getMoney
, в надежде понять, почему существуют разные случаи.
Название getMoneyIfHasOnePerson
не выглядит правильно. Исходя из названия, я ожидаю, что метод проверит, есть ли один человек, и, если это так, получит от него деньги; в противном случае ничего не делать. Из вашего кода это не то, что происходит (или вы выполняете условие дважды).
Есть ли причина возвращать List<Money>
коллекцию, а не коллекцию?
Возвращаясь к вашему вопросу, поскольку неясно, почему существует специальный режим для одного человека, цифру один следует заменить константой, если нет другого способа сделать правила явными. Здесь одно не сильно отличается от любого другого магического числа. У вас могут быть деловые правила, гласящие, что специальный режим применяется к одному, двум или трем лицам или только к более чем двенадцати лицам.
Как я могу различить контекст, чтобы выбрать лучшее решение?
Вы делаете все, что делает ваш код более явным.
Пример 1
Представьте себе следующий фрагмент кода:
if (sequence.size() == 0) {
return null;
}
return this.processSequence(sequence);
Ноль здесь магическая ценность? Код довольно прост: если в последовательности нет элементов, давайте не будем обрабатывать их и возвращать специальное значение. Но этот код также можно переписать так:
if (sequence.isEmpty()) {
return null;
}
return this.processSequence(sequence);
Здесь больше нет констант, а код еще понятнее.
Пример 2
Возьмите другой кусок кода:
const result = Math.round(input * 1000) / 1000;
Не требуется много времени, чтобы понять, что он делает в таких языках, как JavaScript, которые не round(value, precision)
перегружены.
Теперь, если вы хотите ввести константу, как бы она называлась? Ближайший срок вы можете получить Precision
. Так:
const precision = 1000;
const result = Math.round(input * precision) / precision;
Это улучшает читабельность? Это может быть. Здесь значение константы довольно ограничено, и вы можете спросить себя, действительно ли вам нужно выполнить рефакторинг. Приятно то, что теперь точность объявляется только один раз, поэтому, если она изменится, вы не рискуете ошибиться, например:
const result = Math.round(input * 100) / 1000;
изменить значение в одном месте и забыть сделать это в другом.
Пример 3
Из этих примеров у вас может сложиться впечатление, что числа должны быть заменены константами в каждом случае . Это неправда. В некоторых ситуациях наличие константы не приводит к улучшению кода.
Возьмите следующий кусок кода:
class Point
{
...
public void Reset()
{
x, y = (0, 0);
}
}
Если вы попытаетесь заменить нули на переменную, сложность будет найти значимое имя. Как бы вы назвали это? ZeroPosition
? Base
? Default
? Введение здесь константы никак не улучшит код. Это сделало бы это немного длиннее, и только это.
Такие случаи, однако, редки. Поэтому каждый раз, когда вы находите число в коде, старайтесь найти способ реорганизации кода. Спросите себя, есть ли деловое значение для числа. Если да, константа обязательна. Если нет, как бы вы назвали номер? Если вы найдете значимое имя, это здорово. Если нет, скорее всего, вы нашли случай, когда константа не нужна.
persons
и что это описывает? Ваш код не имеет никаких комментариев, поэтому трудно угадать, что он делает.