З цим фрагментом коду є кілька проблем, які, до речі, можна скоротити так:
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
і що в ньому описується? Ваш код не має жодних коментарів, тому важко здогадатися, що він робить.