JavaRush /Java блог /Random UA /Глобальні змінні Java: коли їх використовувати?
Анзор Кармов
31 рівень
Санкт-Петербург

Глобальні змінні Java: коли їх використовувати?

Стаття з групи Random UA
Вітання! У цій статті ми поговоримо про глобальні змінні, про їх оголошення та приклади доречного використання. Невелика примітка: ми не розглядатимемо глобальні змінні класу, тобто ті, доступ до яких є в рамках одного класу. Будемо говорити про глобальні змінні всього додатка — тих, доступ до яких є в рамках цілої програми. Глобальні змінні Java: коли їх використовувати?  - 1

Як створювати глобальні змінні

Глобальні змінні — це змінні, які доступні у програмі. Інакше кажучи, їх область видимості — вся програма. Щоб створити таку змінну Java, необхідно в публічному класі створити публічну статичну змінну:
public class Example {
    public static int a;
    public static int b;
    public static String str;
}
Змінні a, bі strстали глобальними. Ми можемо отримати до них прямий доступ з інших класів усередині програми:
public class GlobalVarsDemo {
    public static void main(String[] args) {
        Example.a = 4;
        Example.b = 5;
        Example.str = "Global String variable value";

        System.out.println(Example.a);
        System.out.println(Example.b);
        System.out.println(Example.str);
    }
}
Якщо ми запустимо метод main, то побачимо наступний висновок:

4
5
Global String variable value
Глобальні змінні можна розділити на 2 типи:
  • змінні, які можна редагувати;
  • змінні, які можна лише зчитувати.
Останні називають глобальними константами. Для того, щоб створити глобальну константу, необхідно зробити змінну finalі надати їй значення при визначенні змінної:
public class Constants {

    public static final double PI = 3.1415926535897932384626433832795;
    public static final String HELLO_WORLD_STR = "Hello, World!";

}
За згодою про ім'я в ЯП Java, всі константи необхідно назвати у верхньому регістрі, розділяючи слова символом нижнього підкреслення. Отже, ми створабо константи, і тепер ми не зможемо змінювати їх значення: Глобальні змінні Java: коли їх використовувати?  - 2Однак ми можемо зчитувати їх значення:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println(Constants.HELLO_WORLD_STR);
    }
}
Висновок:

Hello, World!
public class ConstantsDemo {
    public static void main(String[] args) {
        double r = 10;
        String message = String.format("Площадь круга с радиусом %f=%f", r, getCircleSquare(r));
        System.out.println(message);

    }

    static double getCircleSquare(double r) {
        return Constants.PI * r * r;
    }
}
Висновок:

Площадь круга с радиусом 10,000000=314,159265

Чи варто використовувати глобальні змінні

В інтернеті багато статей, основне посилання яких таке: глобальні змінні - це зло, погано і жахливо. Чи це так насправді? Спробуємо навести плюси та мінуси глобальних змінних, щоб кожен міг зробити висновок самостійно. Глобальні змінні Java: коли їх використовувати?  - 3Почнемо з мінусів. Уявімо додаток, у якому є клас із глобальними змінними, доступними для читання та редагування. Згодом у проекті зростає кількість класів, кількість глобальних змінних та методів, які використовують глобальні змінні, а іншими словами залежать від них. Згодом, кожна глобальна змінна зчитується в різних частинах системи для різних цілей. У різних частинах системи значення змінної може оновлюватися. Загальна картина світу цього додатка істотно ускладнюється, і звідси випливають такі мінуси :
  1. Зниження читабельності та збільшення складності розуміння коду.
  2. Збільшення складності супроводу коду.
  3. Для зміни однієї глобальної змінної необхідно проаналізувати весь код, щоб не задати змінної невалідне для інших частин системи значення.
  4. Збільшення помилок, які дуже складно налагоджувати.

    Уявімо глобальну змінну, масив об'єктів. В одній частині системи в даному масиві очікуються рядки, а в іншій частині системи хтось вирішив використовувати числа з плаваючою точкою. Навряд чи комусь захочеться в такому розумітися.

  5. Імена змінних можуть збігтися, якщо ви використовуєте у своєму коді глобальні змінні, а також деякі бібліотеки, в яких також використовуються глобальні змінні. Це може призвести до помилок як на стороні вашої програми, так і на стороні бібліотеки, що використовується.
  6. Збільшується зв'язок між різними частинами системи, які використовують глобальні змінні. Прагнути потрібно навпаки до слабкої зв'язаності коду. Краще мати багато маленьких підсистем, слабко пов'язаних один з одним, ніж одну велику фіговину. Тому що мозку легше розбиратися з кількома простими речами, ніж із однією надто складною та заплутаною штукою.
  7. Написання юніт-тестів ускладнюється, оскільки тесту не відомо, які глобальні змінні потрібні і як їх необхідно проініціалізувати.
  8. У багатопотокових додатках використання глобальних змінних різними потоками призводить до зростання помилок, які складно налагоджувати, та до зростання складності проекту. Через це необхідно налаштовувати доступ до таких змінних більш правильно, обвішуючи їх синхронізаціями та блокуваннями. У майбутньому це може призвести до замкнених блокувань. Наприклад, потік А заблокував для своєї роботи змінну X, а потік B заблокував для своєї роботи змінну Y, а потоку А тепер потрібна змінна Y, а потоку B змінна X. У результаті програма зависне.
Але все це неточно. Це опис ризиків, ймовірність яких збільшується зі зростанням проекту та зростанням кількості глобальних змінних у ньому. Перейдемо до плюсів :
  1. У маленьких проектах глобальні змінні — найпростіша річ задля досягнення працездатності проекту.
  2. Іноді страх використання глобальних змінних призводить до ще більшого ускладнення проекту. Тоді програмісти починають створювати синглтони та вдаватися до інших шаблонів проектування.
  3. У програмуванні часто буває потрібно спиратися деякі незмінні значення.

    Найрозумніше — записати такі значення у вигляді константи, бо лише константи дають гарантію, що значення змінної не зміниться з часом. Такі константи можна зустріти часто-густо ( Integer.MAX_VALUE, Integer.MIN_VALUE, Boolean.TRUE, Collections.EMPTY_LISTта ін.). Але програмування не обмежується використанням стандартних бібліотек. Часто буває потрібно писати якусь унікальну логіку, в якій необхідно буде спиратися на свої унікальні константи. Тому часом використання констант (глобальних змінних, доступних лише читання) справді спрощує життя.

Загалом не варто зловживати глобальними змінними, по можливості використовувати лише константи. Раніше було сказано, що використовувати глобальні змінні у маленьких проектах – це непогано. Але розробнику-початківцю краще взагалі їх не використовувати. З двох причин:
  1. Все, що пише розробник-початківець — по суті невеликий проект. І використання у його проектах глобальних змінних привчить його до використання глобальних змінних скрізь.
  2. Краще навчитися спочатку обходитися без «заборонених приймачів». А з досвідом розуміння, коли такі приймачі доречно застосовувати, прийде саме.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ