Quando é bom usar uma variável Global

22

Ok, então essa é realmente uma questão de advogado do diabo.

Quando as variáveis ​​globais estão corretas e, se nunca, o que você usaria como alternativa?

Um caso secundário interessante para essa pergunta: como um campo público de classe estática é diferente de um global?

ocodo
fonte
5
Código Completo , 2ª edição, §13.3.
Jerry Coffin
1
Aplicativos multithread requerem praticamente variáveis ​​globais.
água
4
@aqua Os aplicativos multithread são onde as variáveis ​​globais podem ser mais prejudiciais. Todo mundo odeia lógica de bloqueio complexa.
luiscubal
1
@JerryCoffin Se postar um link como resposta sem citar a passagem relevante é uma prática ruim, então citar uma seção de um livro sem citar a passagem relevante. Especialmente porque os livros não podem ser obtidos de maneira fácil e gratuita, como as páginas da web.
Braden Best

Respostas:

18

Até onde eu sei, um campo estático público é basicamente global, uma vez que pode ser chamado de qualquer lugar, com a exceção de que não obstrui o espaço para nome.

A única vez que eu pessoalmente uso variáveis ​​'globais' no meu código é na forma de campos estáticos públicos que são imutáveis. Nesse caso, não há necessidade de se preocupar com o valor que está sendo danificado por outras partes do programa e, claro, é muito melhor do que ter uma dúzia de variáveis ​​com os mesmos valores permanentes em cada classe.


fonte
2
Eu chamaria um campo imutável de constante .
aioobe 31/01
14

Pessoalmente, eu uso globals para configuração de tempo de execução - se uma propriedade de configuração é carregada na inicialização do aplicativo e muda apenas com pouca frequência (e somente então de um local), é terrível e propenso a erros transmiti-lo a todos os métodos que possam precisar ser usados em algum momento. É melhor usar algo que possa ser colocado no escopo de qualquer lugar que precise usá-lo, pois isso não atrapalha e obscurece as assinaturas de método e os sites de chamada.

Anon.
fonte
Você usaria um global puro para isso ou para uma estática pública / Singleton?
Ocodo 15/02
1
@ Slomojo: Definitivamente não é um singleton. Dependendo da situação, estática em uma classe de configuração ou globais simples com um CONFIG_ou CFG_prefixo.
Anon.
+1, a única alteração que eu sugeriria é dizer "... propenso a erros para transmiti-lo a todos os outros métodos de todas as outras classes". Caso contrário, pode-se atribuir um escopo à classe com o que serve - singleton, eu acho.
22412 Michael Durrant
8

Excluindo sistemas embarcados / em tempo real, você deve usar apenas globais para valores constantes. Se você sente que não pode resolver seu problema sem eles, provavelmente está fazendo algo errado.

Além disso, observe o padrão Singleton , pois fornece uma solução melhor para os globais nessas situações em que você precisa de algo para ter um ponto de acesso global.

Davor Ždralo
fonte
8
Eu provavelmente sugeriria evitar Singletons.
Ocodo 15/02
Não estou sugerindo que os singletons sejam ótimos, mas ainda acho que eles superam muito as variáveis ​​globais.
Davor Ždralo
Valores constantes precisam estar acessíveis apenas na área / módulo em que são relevantes. Uma constante TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPé relevante apenas no arquivo / classe / seção em que 'esse loop específico' aparece.
Cthulhu
1
Os campos de um singleton são variáveis ​​globais, então não vejo como há alguma diferença.
sleske
1
@Cthulhu, deixe-me citar: "naquelas situações em que você precisa de algo para ter um ponto de acesso global".
Davor Ždralo
6

O problema com variáveis ​​globais é que você precisa estar ciente delas em todos os lugares do seu código. No entanto, depois que você decide que precisa conhecer um determinado mundo global, há pouco mais a perder usando-o intensamente. Portanto, minha opinião é que você deve ter muito poucas variáveis ​​globais, mas as poucas que você possui, deve obter o máximo de milhas.

Para outro exemplo de algo que me sinto assim, veja o uso de mixins no Ruby.

btilly
fonte
Que exemplo de casos de uso você sugeriria para esses usos de globais?
Ocodo 15/02
1
@ Slomojo: Um exemplo de globais que não me importo é o uso de @ ARGV e $ _ no Perl. Um exemplo que me importo é o uso de globais para passagem barata de parâmetros para sub-rotinas.
btilly
5

É tudo sobre namespaces.

Imagine por um momento que todos no mundo tenham o mesmo sobrenome. Que bagunça.

(Na Índia, os sikhs têm o mesmo sobrenome: Singh - dê uma olhada)

Christopher Mahan
fonte
6
É usado para ser tudo sobre namespaces, mas agora é sobre a segurança do thread.
dan04
6
@ dan04 Trata-se de não ter um design hediondo com ação assustadora à distância.
Tom Hawtin - tackline
2
@ Tom: Talvez possamos chamar isso de "programação quântica", com linguagem irônica
Christopher Mahan
4

Versão curta: quando facilita o raciocínio sobre o programa. Normalmente, os casos são algum tipo de estado global ou recurso estático amplamente utilizado.

Versão longa: Tom Hawtin disse "com uma ação assustadora à distância" ... esse é exatamente o problema dos globais - você precisa saber onde ele está sendo usado e como, ou pode ser esquisito e difícil de rastrear insetos. Locais não são nada mais ou menos que uma estratégia para reduzir o escopo do que o programador precisa entender para raciocinar sobre o programa.

Outro lado do problema de saber onde eles são usados ​​é que você pode acabar com globais duplicados - nesse caso, as coisas podem ficar realmente estranhas à medida que a maioria dos programas obtém e define var1, enquanto em alguns lugares o var2 é usado para armazenar a mesma informação. Especialmente quando várias pessoas estão trabalhando no mesmo código. Os IDEs podem ser úteis para encontrar o uso, reduzindo o custo dos globais, mas eles não fazem nada pelas duplicatas.

Quanto mais globais você tiver, mais difícil será acompanhar o que está acontecendo com eles. Eles devem ser poucos e distantes entre si.

jmoreno
fonte
Em última análise, ter globais mutáveis ​​é uma péssima idéia. A única exceção decente é quando se trabalha com pegadas de hardware extremamente apertadas, como na programação incorporada. No mínimo, os candidatos a globais em programação regular devem ser divididos em membros estáticos de classes ou módulos, qualquer coisa que seja mutável também deve ser considerada um caso especial, duplamente quando se trabalha em um ambiente multithread. Usando bloqueio / futuros / promessas ou algum outro método de segurança de segmento / transação. - Como ninguém mais mencionou, veja o problema dos filósofos do jantar.
Ocodo 19/08/2013
1
Sem dúvida, os threads podem dificultar o trabalho de globos mutáveis, mas você pode obter o mesmo problema básico devido a eventos. Concordo com a sugestão de colocar a bainha como membros estáticos, e iria além e diria que, idealmente, eles deveriam ser membros estáticos PRIVADOS.
jmoreno
3

Os dois truques com globais e singletons são testabilidade e capacidade de implantação.

Para os testes, eu já vi muitos equipamentos de teste excessivamente complexos apenas para lidar com vidas globais e singleton mal planejadas. Certifique-se de que esse objeto tenha regras de inicialização e remoção claras e simples.

Quanto à capacidade de implantação, há dois casos a serem considerados. Primeiramente, como viverá seu objeto global? Está em uma biblioteca estática ou dinâmica? Se esse objeto global for reutilizado para um plug-in, você obterá cópias extras? Em segundo lugar, o que acontece quando esse objeto global é descartado em um aplicativo paralelo? É thread-safe?

No geral, acho que essas razões significam que globals e singletons são usados ​​apenas excepcionalmente.

smithco
fonte
2

O desenvolvimento de sistemas embarcados críticos geralmente envolve o uso de variáveis ​​globais.

Os tamanhos das pilhas são pequenos, tudo é alocado estaticamente ( malloc()é proibido), as variáveis ​​globais estão ocultas fora da biblioteca a que pertencem.

mouviciel
fonte
0

Em uma horrível base de código VB6 que abusa dos globais como se não houvesse amanhã, sou culpado de apresentar uma nova:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

Eu acho que é um dos poucos casos de uso válidos para um objeto global.

Mathieu Guindon
fonte