Заміна магічного числа символьною константою
Проблема
В коді використовується число, яке несе якийсь певний сенс.
Рішення
Замініть це число константою з такою назвою, що пояснює сенс цього числа.
double potentialEnergy(double mass, double height) {
return mass * height * 9.81;
}
static final double GRAVITATIONAL_CONSTANT = 9.81;
double potentialEnergy(double mass, double height) {
return mass * height * GRAVITATIONAL_CONSTANT;
}
double PotentialEnergy(double mass, double height)
{
return mass * height * 9.81;
}
const double GRAVITATIONAL_CONSTANT = 9.81;
double PotentialEnergy(double mass, double height)
{
return mass * height * GRAVITATIONAL_CONSTANT;
}
function potentialEnergy($mass, $height) {
return $mass * $height * 9.81;
}
define("GRAVITATIONAL_CONSTANT", 9.81);
function potentialEnergy($mass, $height) {
return $mass * $height * GRAVITATIONAL_CONSTANT;
}
def potentialEnergy(mass, height):
return mass * height * 9.81
GRAVITATIONAL_CONSTANT = 9.81
def potentialEnergy(mass, height):
return mass * height * GRAVITATIONAL_CONSTANT
potentialEnergy(mass: number, height: number): number {
return mass * height * 9.81;
}
static const GRAVITATIONAL_CONSTANT = 9.81;
potentialEnergy(mass: number, height: number): number {
return mass * height * GRAVITATIONAL_CONSTANT;
}
Причини рефакторингу
Магічні числа — це числові значення, що зустрічаються в коді, але при цьому не очевидно, що вони означають. Цей антипатерн ускладнює розуміння програми, а також її рефакторинг.
Додаткові складнощі виникають, коли треба поміняти певне магічне число. Це не можна зробити автозаміною, оскільки одне і те ж число може використовуватися для різних цілей, тобто вам треба буде перевіряти кожну ділянку коду, де використовується це число.
Переваги
-
Символьна константа може служити живою документацією, пояснюючи сенс значення, яке в ній зберігається.
-
Значення константи набагато простіше замінити, ніж шукати потрібне число по всьому коду, ризикуючи при цьому замінити таке ж число, яке використовувалося для інших цілей.
-
Прибирає дублювання використання числа або рядка по всьому коду. Це особливо актуально, якщо значення є складним і довгим (наприклад,
-14159
,0xcafebabe
).
Корисні факти
Не всі числа є магічними
Якщо призначення чисел очевидні, їх не потрібно замінювати константами, класичний приклад:
Альтернативи
-
Іноді магічне число можна замінити викликом методу. Наприклад, якщо у вас є магічне число, що означає кількість елементів колекції, вам не обов’язково використовувати його для перевірок останнього елементу колекції. Замість цього можна використати вбудований метод отримання довжини колекції.
-
Магічні числа можуть бути використані для реалізації кодування типу. Наприклад, у вас є два типи користувачів, і щоби позначити їх, у вас є числове поле в класі, в якому для адміністраторів зберігається число
1
, а для простих користувачів — число2
.В цьому випадку має сенс використати один з рефакторингів позбавлення від кодування типу:
Порядок рефакторингу
-
Оголосіть константу і присвойте їй значення магічного числа.
-
Знайдіть усі згадки магічного числа.
-
Для всіх знайдених чисел перевірте, чи узгоджується це магічне число з призначенням константи. Якщо так, замініть його вашою константою. Ця перевірка важлива, оскільки одне і теж число може означати абсолютно різні речі (в цьому випадку, вони мають бути замінені різними константами).