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


22

Гаразд, це справді дещо питання захисника чортів.

Коли глобальні змінні нормальні, і якщо ніколи, що б ви використовували як альтернативу?

Цікавий бік цього питання, чим суспільне поле статичного класу відрізняється від глобального?


5
Кодекс повний , 2-е видання, §13.3.
Джеррі Труну

1
Багатопотокові програми дуже потребують глобальних змінних.
аква


4
@aqua Багатопотокові програми - це те, де глобальні змінні можуть бути найбільш згубними. Усі ненавидять складну логіку блокування.
luiscubal

1
@JerryCoffin Якщо розміщення посилання як відповідь, не цитуючи відповідний уривок, є поганою практикою, тоді це цитування розділу книги без цитування відповідного уривку. Тим більше, що книги не є вільно і легко доступними, як веб-сторінки.
Бреден Кращий

Відповіді:


18

Наскільки я знаю, публічне статичне поле в основному є глобальним, враховуючи, що його можна викликати з будь-якого місця, за винятком того, що воно не засмічує простір імен.

Єдиний раз, коли я особисто використовую «глобальні» змінні у своєму коді, є у вигляді публічних статичних полів, незмінних. У цьому випадку не потрібно турбуватися про те, що значення накручується іншими частинами програми, і, звичайно, це набагато приємніше, ніж мати десяток змінних з однаковими постійними значеннями в кожному класі.


2
Я б назвав незмінне поле постійною .
aioobe

14

Особисто я використовую глобалі для конфігурації виконання - якщо властивість конфігурації завантажується під час запуску програми і змінюється нечасто (і лише потім з одного місця), це жахливо і схильне до помилок передавати її навколо кожного методу, який може знадобитися використовувати це в якийсь момент. Краще використовувати щось, що може бути введено в сферу застосування з будь-якого місця, де потрібно його використовувати, оскільки це не захаращує та не затьмарює ваші підписи методів та сайти для викликів.


Чи використовуєте ви чисту глобальну для цього або загальнодоступну статику / Singleton?
окудо

1
@Slomojo: Однозначно не сингл. Залежно від ситуації, або статики класу конфігурації, або звичайні глобали з CONFIG_або CFG_префіксом.
Анон.

+1, я б запропонував змінити: "... схильний до помилок, щоб передати її всім іншим методам у кожному другому класі". Інакше до класу можна віднести те, що служить - я думаю, що одиночний.
Майкл Дюрант

8

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

Крім того, погляньте на схему Singleton , холодне забезпечення кращого рішення для глобальних мереж у тих ситуаціях, коли вам потрібно щось мати глобальну точку доступу.


8
Я, мабуть, запропонував би уникати Сінглтон.
окудо

Я не припускаю, що одиночні чудові, але я все ж думаю, що вони значно перемагають глобальні змінні.
Давор Ждрало

Постійні значення повинні бути доступними лише у відповідній області / модулі. Константа TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPдоречна лише в одному файлі / класі / розділі, де відображається "цей певний цикл".
Cthulhu

1
Поля сингтона є глобальними змінними, тому я не бачу різниці.
sleske

1
@Cthulhu дозвольте мені процитувати себе: "у тих ситуаціях, коли вам потрібно щось мати глобальну точку доступу".
Давор Ждрало

6

Проблема глобальних змінних полягає в тому, що вам потрібно знати про них скрізь у своєму коді. Однак після того, як ви вирішили, що вам потрібно знати про певний глобальний, в його значній мірі втрачається мало. Тому, на мою думку, у вас має бути дуже мало глобальних змінних, але декілька, які у вас є, вам слід отримати максимальний пробіг.

Ще один приклад того, що я відчуваю таким чином, подивіться на використання міксинів у Ruby.


Який приклад використання ви б запропонували для цих цілей глобалізації?
ocodo

1
@Slomojo: Приклад глобальних компаній, які я не заперечую, - це використання @ARGV та $ _ у Perl. Я маю на увазі використання глобалів для дешевого переходу параметрів у підпрограми.
btilly

5

Вся справа в просторах імен.

Уявіть на мить, що всі в світі мали одне і те ж прізвище. Який безлад.

(В Індії у сикхів все те ж прізвище: Сінгх - Поглянь)


6
Він використовується , щоб бути все про просторах імен, але зараз мова йде про безпеку потоку.
dan04

6
@ dan04 Йдеться про те, щоб не мати жахливого дизайну з моторошною дією на відстані.
Том Хотін - тайклін

2
@Tom: Можливо, ми можемо так назвати, що завгодно, "Квантове програмування"
Крістофер Махан

4

Коротка версія: коли це полегшує міркування про програму. Зазвичай випадки - це якийсь тип глобального стану або статичний ресурс, який широко використовується.

Довга версія: Том Хоутін сказав: "з моторошними діями на відстані" ... саме в цьому проблема глобалів - ви повинні знати, де це використовується і як, або ви можете отримати справді дивне і важке для відстеження клопи. Місцеві жителі - це ні що інше, як стратегія зменшення обсягу того, що потрібно зрозуміти програмісту, щоб розмірковувати про програму.

Інша сторона проблеми з тим, щоб знати, де вони використовуються, полягає в тому, що ви можете отримати дублікати глобальних мереж - у цьому випадку речі можуть стати справді дивними, оскільки більшість програм отримує і встановлює var1, а в двох місцях var2 використовується для утримання та сама інформація. Особливо, коли над одним і тим же кодом працює кілька людей. IDE можуть бути корисними для пошуку використання, зменшуючи вартість глобальних компаній, але вони нічого не роблять для дублікатів.

Чим більше глобалів, тим важче вам слідкувати за тим, що з ними відбувається. Їх повинно бути мало і далеко між ними.


Зрештою, мати мінливі глобалі - досить погана ідея. Єдиний гідний виняток - це робота в надзвичайно жорстких апаратних слідах, наприклад, із вбудованим програмуванням. Принаймні, кандидати на глобальні програми в регулярному програмуванні повинні бути розділені на статичні члени класів або модулів, все, що можна змінити, також слід розглядати як окремий випадок, вдвічі, коли вони працюють у багатопотоковому середовищі. Використання блокування / ф'ючерсів / обіцянок або іншого способу безпеки потоку / транзакцій. - Оскільки ніхто більше не згадував про це, ми бачимо проблему філософів їдальні.
ocodo

1
Без сумніву, нитки можуть зробити складнішими глобальні глобальні роботи важче, але ви можете отримати ту саму основну проблему через події. Я погоджуюсь із пропозицією ставити його в якості статичних членів, і я б пішов далі і сказав, що в ідеалі вони повинні бути ЧАСНИМИ статичними членами.
jmoreno

3

Два ґетчі з глобальними та одинарними - це перевірка та розгорнутість.

Для тестування я бачив занадто багато надмірно складних джгутів для тестування, щоб боротися з погано запланованими глобальними та одиночними життями. Переконайтеся, що в будь-якому такому об’єкті є чіткі та прості правила запуску та руйнування.

Що стосується розгортання, то слід розглянути два випадки. По-перше, як буде жити ваш глобальний об’єкт? Чи є в статичній чи динамічній бібліотеці? Якщо цей глобальний об’єкт буде повторно використаний для плагіна, ви отримаєте додаткові копії? По-друге, що відбувається, коли цей глобальний об'єкт потрапляє в паралельну програму? Це безпечно для ниток?

В цілому, я вважаю, що ці причини означають, що глобали та одинаки використовуються лише винятково.


2

Розробка критично вбудованих систем зазвичай передбачає використання глобальних змінних.

Розміри стеків невеликі, все розміщено статично ( malloc()заборонено), глобальні змінні приховані за межами бібліотеки, до якої вони належать.


0

У жахливій базі коду VB6, яка зловживає глобалами, як ні завтра, я винен у введенні нового:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Я думаю, що це один з небагатьох дійсних випадків використання глобального об’єкта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.