Kiedy można użyć zmiennej globalnej?

22

Ok, więc to naprawdę jest trochę diabelskie pytanie.

Kiedy zmienne globalne są w porządku, a jeśli nigdy, to czego byś użył jako alternatywy?

Ciekawym przypadkiem pobocznym tego pytania, w jaki sposób publiczne pole klasy statycznej różni się od globalnego?

ocodo
źródło
5
Kod zakończony , wydanie drugie, § 13.3.
Jerry Coffin
1
Aplikacje wielowątkowe prawie wymagają zmiennych globalnych.
aqua
Patrz Software Coupling
PP.
4
@aqua Aplikacje wielowątkowe to takie, w których zmienne globalne mogą być najbardziej szkodliwe. Wszyscy nie znoszą skomplikowanej logiki blokowania.
luiscubal
1
@JerryCoffin Jeśli opublikowanie linku jako odpowiedzi bez cytowania odpowiedniego fragmentu stanowi złą praktykę, to cytowanie fragmentu książki bez cytowania odpowiedniego fragmentu. Zwłaszcza, że ​​książki nie są tak łatwo dostępne, jak strony internetowe.
Braden Best

Odpowiedzi:

18

O ile mi wiadomo, publiczne pole statyczne jest zasadniczo globalne, biorąc pod uwagę, że można je wywoływać z dowolnego miejsca, z tym wyjątkiem, że nie zatyka przestrzeni nazw.

Jedyny raz, kiedy osobiście używam zmiennych „globalnych” w moim kodzie, mają postać publicznych pól statycznych, które są niezmienne. W tym przypadku nie trzeba się martwić, że wartość zostanie przekręcona przez inne części programu i oczywiście jest o wiele ładniejsza niż posiadanie tuzina zmiennych o takich samych stałych wartościach w każdej klasie.


źródło
2
Nazwałbym niezmienne pole stałą .
aioobe
14

Osobiście używam globałów do konfiguracji środowiska wykonawczego - jeśli właściwość konfiguracji jest ładowana przy uruchamianiu aplikacji i zmienia się rzadko (i tylko wtedy z jednego miejsca), przekazanie jej do każdej metody, która może wymagać użycia, jest okropne i podatne na błędy. w pewnym momencie. Lepiej jest użyć czegoś, co można wprowadzić z dowolnego miejsca, które tego potrzebuje, ponieważ nie zaśmieca to i nie zasłania podpisów metod i stron wywołujących.

Zaraz.
źródło
Czy użyłbyś do tego czystego globalnego lub publicznego statycznego / Singletona?
ocodo
1
@Slomojo: Zdecydowanie nie singleton. W zależności od sytuacji albo statyka w klasie konfiguracji, albo zwykłe globale z prefiksem CONFIG_lub CFG_.
Anon.
+1 jedyną zmianą, którą zasugerowałem, jest powiedzenie „… podatne na błędy, aby przekazać ją każdej innej metodzie w każdej innej klasie”. W przeciwnym razie można objąć zasięgiem wszystko, co służy temu - myślę, że singleton.
Michael Durrant
8

Wyłączając systemy czasu rzeczywistego / wbudowane, naprawdę powinieneś używać globałów tylko do stałych wartości. Jeśli uważasz, że nie możesz rozwiązać problemu bez nich, prawdopodobnie robisz coś złego.

Spójrz również na wzór Singleton , zimno zapewnia lepsze rozwiązanie dla globali w sytuacjach, gdy potrzebujesz czegoś, aby mieć globalny punkt dostępu.

Davor Ždralo
źródło
8
Prawdopodobnie sugerowałbym unikanie Singletonów.
ocodo
Nie sugeruję, że singletony są świetne, ale nadal uważam, że znacznie pobiły globalne zmienne.
Davor Ždralo,
Stałe wartości muszą być dostępne tylko w odpowiednim obszarze / module. Stała TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPma znaczenie tylko w jednym pliku / klasie / sekcji, w której pojawia się „ta konkretna pętla”.
Cthulhu
1
Pola singletonu zmiennymi globalnymi, więc nie widzę żadnej różnicy.
śleske,
1
@ Cthulhu pozwól mi zacytować siebie: „w sytuacjach, gdy potrzebujesz czegoś, aby mieć globalny punkt dostępu”.
Davor Ždralo
6

Problem ze zmiennymi globalnymi polega na tym, że musisz być ich świadomym wszędzie w kodzie. Jednak gdy już zdecydujesz, że musisz wiedzieć o konkretnej globalnej kulturze, nie będziesz już więcej tracić z jej intensywnego korzystania. Dlatego uważam, że powinieneś mieć bardzo niewiele zmiennych globalnych, ale tych, które masz, powinieneś uzyskać maksymalny przebieg.

Innym przykładem czegoś, co tak myślę, jest użycie mixin w Ruby.

btilly
źródło
Jakie przykłady zastosowania sugerowałbyś dla tych zastosowań globali?
ocodo
1
@Slomojo: Przykładem globali Nie mam nic przeciwko użyciu @ARGV i $ _ w Perlu. Przykład, który mam na myśli, to użycie globałów do taniego przekazywania parametrów do podprogramów.
btilly,
5

Chodzi o przestrzenie nazw.

Wyobraź sobie przez chwilę, że wszyscy na świecie mają to samo nazwisko. Co za bałagan.

(W Indiach sikhowie mają to samo nazwisko: Singh - spójrz)

Christopher Mahan
źródło
6
Jest stosowany jako o przestrzeni nazw, ale teraz chodzi o bezpieczeństwo wątku.
dan04
6
@ dan04 Chodzi o to, aby nie mieć ohydnego projektu z upiorną akcją na odległość.
Tom Hawtin - tackline
2
@Tom: Może możemy to nazwać, z przymrużeniem oka, „Programowaniem kwantowym”
Christopher Mahan
4

Wersja skrócona: gdy ułatwia zrozumienie programu. Zazwyczaj przypadki to jakiś rodzaj globalnego stanu lub zasobu statycznego, który jest szeroko stosowany.

Długa wersja: Tom Hawtin powiedział „z upiorną akcją na odległość” ... to jest dokładnie problem z globalsami - musisz wiedzieć, gdzie jest używany i jak, lub możesz dostać naprawdę dziwne i trudne do wyśledzenia robaki. Miejscowi to nic innego jak strategia zmniejszania zakresu tego, co programiści muszą zrozumieć, aby rozumować o programie.

Inną stroną problemu związanego z wiedzą, gdzie są używane, jest to, że możesz skończyć z duplikatami globali - w takim przypadku rzeczy mogą stać się naprawdę dziwne, ponieważ większość programów dostaje i ustawia var1, podczas gdy w kilku miejscach var2 służy do przechowywania te same informacje. Szczególnie, gdy wiele osób pracuje nad tym samym kodem. IDE mogą być pomocne w znalezieniu użycia zmniejszającego koszt globałów, ale nie robią nic dla duplikatów.

Im więcej globali, tym trudniej jest śledzić, co się z nimi dzieje. Powinny być nieliczne i dalekie.

jmoreno
źródło
Ostatecznie posiadanie zmiennych globali jest dość złym pomysłem. Jedynym przyzwoitym wyjątkiem jest praca w bardzo ciasnych urządzeniach, na przykład przy programowaniu wbudowanym. Przynajmniej kandydaci na globals w zwykłym programowaniu powinni być podzieleni na statyczne elementy klas lub modułów, wszystko, co można modyfikować, powinno być również uważane za szczególny przypadek, podwójnie w przypadku pracy w środowisku wielowątkowym. Korzystanie z blokowania / kontraktów terminowych / obietnic lub innej metody bezpieczeństwa wątków / transakcji. - Ponieważ nikt inny nie wspominał, widzi problem filozofów kulinarnych.
ocodo
1
Bez wątpienia wątki mogą sprawić, że zmienne globale będą trudniejsze do pracy, ale możesz mieć ten sam podstawowy problem z powodu zdarzeń. Zgadzam się z sugestią umieszczenia rąbka jako elementów statycznych i chciałbym pójść dalej i powiedzieć, że idealnie powinny być PRYWATNYMI elementami statycznymi.
jmoreno
3

Dwie gotcha z globalsami i singletonami to testowalność i możliwość wdrożenia.

Do testowania widziałem zbyt wiele zbyt skomplikowanych uprzęży testowych, aby poradzić sobie ze źle zaplanowanymi globalnymi i singletonowymi cyklami życia. Upewnij się, że każdy taki obiekt ma jasne i proste zasady uruchamiania i burzenia.

Jeśli chodzi o możliwość wdrożenia, należy rozważyć dwa przypadki. Po pierwsze, jak będzie żył Twój obiekt globalny? Czy jest to biblioteka statyczna czy dynamiczna? Jeśli ten obiekt globalny zostanie ponownie wykorzystany do wtyczki, czy dostaniesz dodatkowe kopie? Po drugie, co się stanie, gdy ten obiekt globalny zostanie upuszczony do aplikacji równoległej? Czy to jest bezpieczne dla wątków?

Ogólnie rzecz biorąc, uważam, że te przyczyny oznaczają, że globały i singletony są używane tylko wyjątkowo.

smithco
źródło
2

Rozwój krytycznych systemów wbudowanych zwykle wymaga użycia zmiennych globalnych.

Rozmiary stosów są niewielkie, wszystko jest przydzielane statycznie ( malloc()jest zabronione), zmienne globalne są ukryte poza biblioteką, do której należą.

mouviciel
źródło
0

W okropnej bazie kodu VB6, która nadużywa globałów, tak jakby nie było jutra, jestem winna wprowadzenia nowej:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Myślę, że jest to jeden z niewielu poprawnych przypadków użycia dla obiektu globalnego.

Mathieu Guindon
źródło