Por que não devo usar a "Notação húngara"?


122

Eu sei ao que o húngaro se refere - fornecendo informações sobre uma variável, parâmetro ou tipo como prefixo ao seu nome. Todo mundo parece ser irado contra isso, embora em alguns casos pareça ser uma boa idéia. Se sinto que informações úteis estão sendo transmitidas, por que não devo colocá-las exatamente onde estão disponíveis?

Veja também: As pessoas usam as convenções de nomes húngaras no mundo real?


Respostas:


174

A maioria das pessoas usa a notação húngara de maneira errada e está obtendo resultados errados.

Leia este excelente artigo de Joel Spolsky: Fazendo o código errado parecer errado .

Em resumo, a notação húngara, na qual você prefixa seus nomes de variáveis ​​com type(string) (sistemas húngaro) é ruim porque é inútil.

Notação húngara, como pretendida pelo autor, onde você prefixa o nome da variável com kind(usando o exemplo de Joel: sequência segura ou sequência não segura), o chamado Apps Hungarian tem seus usos e ainda é valioso.


5
Bom link, um bom resumo do que está por trás do link e sem fanatismo. Excelente.
Dustman

12
Observe que o exemplo do Joels está no VBScript, uma linguagem que há muito tempo não tinha classes definidas pelo usuário. Em uma linguagem OO, você apenas criaria um tipo HtmlEncodedString e faria com que o método Write aceite apenas isso. Os "aplicativos húngaros" são úteis apenas em idiomas sem tipos definidos pelo usuário.
JacquesB 22/09/08

4
A Microsoft é conhecida por seu mau uso passado da notação húngara. Anexar informações de tipo aos identificadores não é apenas inútil, mas pode realmente causar danos. Primeiro, a legibilidade é menos fluente. Segundo, em idiomas que suportam polimorfismo ou digitação de pato, as informações erradas são passadas.
29510 wilhelmtell

9
Ainda gosto de usar a notação húngara se estiver desenvolvendo diretamente o C com um IDE mais antigo ... dessa forma, sei que não há problemas de conversão de tipo.
Beep beep

3
@ Krumia: Isso normalmente seria evitado com nomes de variáveis ​​descritivos em primeiro lugar. Mas se você quiser ter certeza, seria muito mais seguro criar tipos distintos (por exemplo, estruturas) para comprimentos, pesos etc. e usar sobrecarga do operador para garantir que apenas operações válidas sejam possíveis.
precisa saber é o seguinte

277

vUsando a anotação adjHungarian, torna difícil a leitura do ncode.


101
Boa analogia, embora um pouco injusta. Compare: vUsando o adjHunarian nNotation vMakes nReading nCode adjDifficult.
Chris Noe

27
Nessa frase, Usar e Ler são gerúndios. Mas eu entendi o que você estava fazendo ...
chimpanzé

28
@ chimp: isso torna as coisas ainda mais óbvias. agora que você encontrou um erro no tipo, renomeará todas as referências ou as deixará como estão, fornecendo informações incorretas? você perde de qualquer maneira. mas é claro que essa é a maneira errada de aplicar a notação húngara.
Wilhelmtell

1
@ Chris Noe: para certos estilos de leitura (analise o prefixo e o sufixo com um olhar no meio), seu exemplo só piora as coisas. Vejo "vUsing" e ouço "voosing" na minha cabeça.
22230 Bob Cross

3
@ Jon: se você tem um nome de variável que não divulga completamente o que está representando, então, absolutamente, o foco deve ser renomeá-lo para algo mais descritivo (e a notação húngara não é uma melhoria, muito, muito na melhor das hipóteses, está corrigindo o sintoma - não resolvendo o problema).
precisa saber é o seguinte

104

Joel está errado, e aqui está o porquê.

Essa informação de "aplicativo" de que ele está falando deve ser codificada no sistema de tipos . Você não deve depender da inversão dos nomes das variáveis ​​para garantir que não transmita dados inseguros para funções que exijam dados seguros. Você deve cometer um erro de tipo, para que seja impossível fazê-lo. Quaisquer dados não seguros devem ter um tipo marcado como inseguro, para que simplesmente não possam ser passados ​​para uma função segura. Para converter de inseguro para seguro, é necessário processar com algum tipo de função de higienização.

Muitas das coisas que Joel fala como "tipos" não são tipos; eles são, de fato, tipos.

O que falta na maioria das línguas, no entanto, é um sistema de tipos que seja expressivo o suficiente para impor esse tipo de distinção. Por exemplo, se C tivesse uma espécie de "typedef forte" (onde o nome typedef tinha todas as operações do tipo base, mas não era conversível nele), muitos desses problemas desapareceriam. Por exemplo, se você poderia dizer, strong typedef std::string unsafe_string;para introduzir um novo tipounsafe_string que não pudesse ser convertido em um std :: string (e, portanto, poderia participar da resolução de sobrecarga etc. etc.), não precisaríamos de prefixos tolos.

Portanto, a afirmação central de que o húngaro é para coisas que não são do tipo está errada. Está sendo usado para informações de tipo. Informações mais ricas do que as informações tradicionais do tipo C, certamente; são informações de tipo que codificam algum tipo de detalhe semântico para indicar a finalidade dos objetos. Mas ainda são informações de tipo, e a solução adequada sempre foi codificá-las no sistema de tipos. Codificá-lo no sistema de tipos é, de longe, a melhor maneira de obter validação e aplicação adequadas das regras. Os nomes das variáveis ​​simplesmente não cortam a mostarda.

Em outras palavras, o objetivo não deve ser "fazer com que o código errado pareça errado para o desenvolvedor". Deve ser "fazer com que o código errado pareça errado para o compilador ".


30
A intenção da variável deve ser codificada dentro do tipo da variável, não deixada para algo tão frágil como um esquema de nomeação.
DrPizza 11/11/08

3
Eu adoraria torná-lo o trabalho do compilador / intérprete também, mas isso implicaria uma enorme sobrecarga para linguagens dinâmicas (Python, Ruby, PHP ou Javascript).
muito php

22
"O que falta na maioria das línguas, no entanto, é um sistema de tipos suficientemente expressivo para impor esse tipo de distinção". E aí está o problema. O AppsHungarian é um método pragmático para destacar problemas ao usar essas linguagens de maneira óbvia para programadores que visualizam o código, em vez de examinar os relatórios de erros.
305 Neil Trodden

6
@DrPizza: Eu acredito que você perdeu um dos pontos muito importantes que Joel está defendendo ao defender o Apps Hungarian: essa notação é apenas uma troca muito pragmática . Tornar o compilador capaz de ver "código errado" é um grande objetivo, mas sempre vale o seu custo?
Yarik

4
@DrPizza:, Joel is wronge What most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.Então, como a maioria das línguas não tem expressividade suficiente para impor esse tipo de distinção, Joel está certo. Certo?
Sampathsris

46

Eu acho que isso atrapalha enormemente o código fonte.

Também não ganha muito em uma linguagem fortemente tipada. Se você fizer qualquer forma de incompatibilidade de tipo no tomfoolery, o compilador informará sobre isso.


Uau. 90 repetições em 15 minutos. Boa decisão.
Dustman

2
Se você usá-lo para o tipo, então sim, é inútil. É útil transmitir outras informações.
Lou Franco

12
@Lou, exatamente - Pessoalmente, eu armazenar um histórico de revisão em meus nomes de variáveis: firstName_wasName_wasNameID_wasSweetCupinCakes cordas
Shog9

@nsanders: Tente usar o compilador para verificar se você usou as mesmas unidades de medida quando os dois tipos de variáveis ​​são inteiros.
Igor Levicki

1
@ Shog9: Acho que você não entendeu a Notação Húngara do Google Apps. É mais sobre sFirstName vs unFirstName (seguro vs inseguro, não higienizado), assim você sabe algo mais sobre ele. Ainda acho que, em linguagens estáticas, é melhor subtipo String para criar UnsafeString e SafeString e permitir apenas a saída do SafeString. A convenção está bem, mas (com mais freqüência) as implementações de compilação são melhores.
kgadek

28

A notação húngara só faz sentido em idiomas sem tipos definidos pelo usuário . Em uma linguagem funcional ou OO moderna, você codificaria informações sobre o "tipo" de valor no tipo de dados ou classe, e não no nome da variável.

Várias respostas fazem referência ao artigo de Joels . Observe, no entanto, que seu exemplo está no VBScript, que não suportava classes definidas pelo usuário (por um longo tempo, pelo menos). Em um idioma com tipos definidos pelo usuário, você resolveria o mesmo problema criando um tipo HtmlEncodedString e, em seguida, deixe o método Write aceitar apenas isso. Em uma linguagem digitada estaticamente, o compilador captura qualquer erro de codificação; em uma digitação dinâmica, você recebe uma exceção de tempo de execução - mas, em qualquer caso, você está protegido contra a gravação de strings não codificadas. As notações húngaras transformam o programador em um verificador de tipos humano, com o tipo de trabalho que normalmente é melhor tratado pelo software.

Joel distingue entre "sistemas húngaro" e "aplicativos húngaro", onde "sistemas húngaro" codifica os tipos internos como int, float e assim por diante, e "aplicativos húngaro" codifica "tipos", que é uma meta-informação de nível superior sobre a variável além do tipo de máquina. Em uma linguagem funcional OO ou moderna, é possível criar tipos definidos pelo usuário, para que não haja distinção entre tipo e "tipo" nesse sentido - ambos podem ser representados pelo sistema de tipos - e "apps" húngaro é tão redundante quanto "sistemas" húngaro.

Então, para responder à sua pergunta: Os sistemas húngaros seriam úteis apenas em uma linguagem insegura e de tipo fraco, onde, por exemplo, atribuir um valor flutuante a uma variável int causará um travamento no sistema. A notação húngara foi inventada especificamente nos anos sessenta para uso no BCPL , uma linguagem de baixo nível que não fazia nenhuma verificação de tipo. Não acho que nenhuma linguagem de uso geral hoje tenha esse problema, mas a notação vivia como uma espécie de programação de cultos de carga .

Os aplicativos húngaros farão sentido se você estiver trabalhando com uma linguagem sem tipos definidos pelo usuário, como VBScript herdado ou versões anteriores do VB. Talvez também versões anteriores do Perl e PHP. Novamente, usá-lo em uma linguagem moderna é puro culto à carga.

Em qualquer outro idioma, o húngaro é apenas feio, redundante e frágil. Ele repete as informações já conhecidas do sistema de tipos e você não deve se repetir . Use um nome descritivo para a variável que descreve a intenção dessa instância específica do tipo. Use o sistema de tipos para codificar invariantes e meta-informações sobre "tipos" ou "classes" de variáveis ​​- ie. tipos.

O ponto geral do artigo de Joels - fazer com que um código errado pareça errado - é um princípio muito bom. No entanto, uma proteção ainda melhor contra bugs é - quando possível - ter código incorreto a ser detectado automaticamente pelo compilador.


Idiomas com tipos definidos pelo usuário nem sempre tornam prático o uso de tipos em vez de "tipos". Considere os prefixos "c", "d", "ix" do Apps Hungarian de Joel. Você usa tipos inteiros personalizados para esses, em todos os idiomas modernos? Acho que não. Como os idiomas modernos ainda não possuem tipos inteiros personalizados para índices, contagens e diferenças entre dois números. Enquanto ainda estivermos usando baunilha, o Apps Hungarian não será redundante e útil.
Eldritch Conundrum

27

Eu sempre uso a notação húngara em todos os meus projetos. Acho realmente útil quando estou lidando com centenas de nomes de identificadores diferentes.

Por exemplo, quando chamo uma função que requer uma string, posso digitar 's' e pressionar control-space e meu IDE me mostrará exatamente os nomes das variáveis ​​prefixadas com 's'.

Outra vantagem, quando prefixo u para entradas não assinadas e i para entradas assinadas, vejo imediatamente onde estou misturando assinadas e não assinadas de maneiras potencialmente perigosas.

Não me lembro do número de vezes que, em uma enorme base de código de 75000 linhas, os bugs foram causados ​​(por mim e por outras pessoas também) devido ao nome de variáveis ​​locais iguais às variáveis ​​de membro existentes dessa classe. Desde então, prefixo sempre os membros com 'm_'

É uma questão de gosto e experiência. Não bata até que você tente.


1
Codificar assinatura em nomes de variáveis ​​é excelente quando o trecho de código está realmente lidando com assinatura. Usar isso como uma desculpa para impor a convenção para todas as variáveis ​​é apenas IMHO do domatismo.
Plumenator

Você tem um bom argumento com variáveis ​​de membro, no entanto. Mas em linguagens como Python, onde você é forçado a qualificar membros com esse eu / esse objeto, é discutível.
Plumenator 10/03/12

É apenas um truque para ajudar na produtividade. Assim como o IDE é preenchido automaticamente. Não há nada de fundamentalmente mau nisso. Acredito que codificadores experientes devem ter permissão para usar seu próprio estilo. Forçar alguém a escolher um determinado estilo é ruim. Eu trabalho como desenvolvedor único agora, mas não aplicaria um estilo a ninguém com quem trabalhasse, a menos que eles não tivessem um estilo consistente.
Rep_movsd 13/03/12

Então, você está usando a convenção de nomenclatura para filtrar as variáveis, não é? Devo concordar que é meio inteligente . :-) No entanto, a maneira como estou conectado, o ponto de ancoragem (ou critério de filtro, se você preferir) é sempre a semântica para mim. Raramente o tipo (a menos que seja semântico). Espero que isso faça sentido. TL; DR: Eu ainda ia ficar a variáveis de nomeação de acordo com o que elas representam do que como eles estão representados.
Plumenator

1
Eu votei isso na época porque era a favor do húngaro. Agora eu me arrependo, e nunca voltaria a prefixação algo para uma variável ..
Nawfal

22

Você está esquecendo o motivo número um para incluir essas informações. Não tem nada a ver com você, o programador. Tem tudo a ver com a pessoa descendo a estrada 2 ou 3 anos depois que você sai da empresa que precisa ler essas coisas.

Sim, um IDE identificará rapidamente os tipos para você. No entanto, quando você está lendo alguns lotes longos de código de 'regras de negócios', é bom não precisar fazer uma pausa em cada variável para descobrir que tipo é. Quando vejo coisas como strUserID, intProduct ou guiProductID, facilita muito o tempo de "aceleração".

Concordo que a MS foi longe demais com algumas de suas convenções de nomenclatura - categorizo ​​isso na pilha "muita coisa boa".

As convenções de nomenclatura são boas, desde que você as cumpra. Passei por um código antigo o suficiente para que eu constantemente voltasse a olhar para as definições de tantas variáveis ​​com nomes semelhantes que pressiono "camel case" (como era chamado em um trabalho anterior). No momento, estou em um trabalho que possui muitos milhares de linhas de código ASP clássico completamente não comentado com o VBScript e é um pesadelo tentar entender as coisas.


Como usuário do VIM (sem IDE, sem realce, sem passar o mouse sobre o tipo), não entendo esse argumento. Naturalmente, compreendo que uma variável chamada name é uma string e uma variável chamada i ou count é um int. Você realmente precisa de sName e iCount? Como isso realmente ajuda? Eu diria que o exemplo de identificação do seu produto é um caso especial e talvez seja bom. Mas mesmo assim, ser consistente e representar IDs de produtos com ints ou strings em todos os lugares seria uma solução muito melhor, não é? A coisa toda de nomeação parece uma imitação.
precisa saber é o seguinte

6
É por consistência. Sim, "nome" implica inerentemente uma sequência. Mas o que você presumiria ser "userid"? Um GUID? Corda? Inteiro? Mesmo algo como "acctno" pode ter um valor de 42 ou "23X". A documentação é escassa o suficiente na maioria dos códigos. Esse padrão ajuda o programador de manutenção um pouco.
David

1
@ David Eu concordo totalmente com a sua resposta - sabendo rapidamente a intenção da variável é a razão pela qual prefiro prefixar também, mais ainda em uma linguagem dinâmica como JS.
Daniel Sokolowski

10

Aderir caracteres criptografados no início de cada nome de variável é desnecessário e mostra que o nome da variável por si só não é descritivo o suficiente. A maioria dos idiomas exige o tipo de variável na declaração de qualquer maneira, para que as informações já estejam disponíveis.

Há também a situação em que, durante a manutenção, um tipo de variável precisa ser alterado. Exemplo: se uma variável declarada como "uint_16 u16foo" precisar se tornar um sinal de 64 bits, uma das duas coisas acontecerá:

  1. Você analisará e alterará o nome de cada variável (certificando-se de não manipular nenhuma variável não relacionada com o mesmo nome) ou
  2. Apenas mude o tipo e não o nome, o que só causará confusão.

9

Joel Spolsky escreveu um bom post sobre isso. http://www.joelonsoftware.com/articles/Wrong.html Basicamente, não se trata de dificultar a leitura do código quando um IDE decente diz que você deseja digitar a variável, caso não se lembre. Além disso, se você tornar seu código compartimentado o suficiente, não precisará se lembrar que uma variável foi declarada com três páginas acima.


9

O escopo não é mais importante do que o tipo atualmente, por exemplo

* l for local
* a for argument
* m for member
* g for global
* etc

Com técnicas modernas de refatoração de código antigo, a pesquisa e a substituição de um símbolo porque você alterou seu tipo é tedioso, o compilador capturará alterações de tipo, mas geralmente não capturará uso incorreto do escopo, as convenções de nomenclatura sensatas ajudam aqui.


Por outro lado, o código provavelmente não deve depender tanto do escopo. :-)
Plumenator 10/03/12

8

Não há razão para você não fazer uso correto da notação húngara. Sua impopularidade se deve a uma reação duradoura contra o uso indevido indevido da notação húngara, especialmente nas APIs do Windows.

Nos velhos tempos, antes que existisse algo semelhante a um IDE para o DOS (provavelmente você não tinha memória livre suficiente para executar o compilador no Windows, portanto seu desenvolvimento foi feito no DOS), você não recebeu nenhuma ajuda de passando o mouse sobre o nome de uma variável. (Supondo que você tivesse um mouse.) Com o que você precisou lidar, foram funções de retorno de chamada de eventos nas quais tudo foi passado a você como int de 16 bits (WORD) ou int de 32 bits (LONG WORD). Você teve que converter esses parâmetros nos tipos apropriados para o tipo de evento especificado. De fato, grande parte da API era praticamente sem tipo.

O resultado, uma API com nomes de parâmetros como estes:

LRESULT CALLBACK WindowProc(HWND hwnd,
                            UINT uMsg,
                            WPARAM wParam,
                            LPARAM lParam);

Observe que os nomes wParam e lParam, apesar de terríveis, não são realmente piores do que nomeá-los param1 e param2.

Para piorar a situação, o Windows 3.0 / 3.1 tinha dois tipos de ponteiros, próximos e distantes. Portanto, por exemplo, o valor de retorno da função de gerenciamento de memória LocalLock era um PVOID, mas o valor de retorno do GlobalLock era um LPVOID (com o 'L' por muito tempo). Essa notação terrível depois foi estendido para que uma l ong p ointer cadeia foi prefixado lp , para distingui-lo a partir de uma string que tinha sido simplesmente malloc.

Não é surpresa que houvesse uma reação contra esse tipo de coisa.


6

A notação húngara pode ser útil em idiomas sem verificação de tipo em tempo de compilação, pois permitiria que o desenvolvedor se lembrasse rapidamente de como a variável específica é usada. Não faz nada por desempenho ou comportamento. É suposto melhorar a legibilidade do código e é principalmente uma questão de gosto e estilo de codificação. Por esse motivo, é criticado por muitos desenvolvedores - nem todo mundo tem a mesma fiação no cérebro.

Para as linguagens de verificação de tipo em tempo de compilação, é principalmente inútil - rolar algumas linhas deve revelar a declaração e, assim, digitar. Se suas variáveis ​​globais ou seu bloco de código se estenderem por muito mais de uma tela, você terá problemas graves de design e reutilização. Portanto, uma das críticas é que a notação húngara permite que os desenvolvedores tenham um design ruim e se saiam facilmente facilmente. Esta é provavelmente uma das razões para odiar.

Por outro lado, pode haver casos em que mesmo as linguagens de verificação de tipo em tempo de compilação se beneficiariam da notação húngara - ponteiros nulos ou HANDLE na API win32. Isso ofusca o tipo de dados real e pode haver um mérito em usar a notação húngara lá. No entanto, se é possível conhecer o tipo de dados no momento da construção, por que não usar o tipo de dados apropriado.

Em geral, não há razões difíceis para não usar a notação húngara. É uma questão de gostos, políticas e estilo de codificação.


6

Como programador de Python, a notação húngara se desintegra rapidamente. No Python, eu não me importo se algo é uma string - eu me importo se ele pode agir como uma string (ou seja, se tiver uma___str___() método que retorna uma string).

Por exemplo, digamos que temos foo como um número inteiro, 12

foo = 12

A notação húngara nos diz que devemos chamar isso de iFoo ou algo assim, para denotar que é um número inteiro, para que mais tarde saibamos o que é. Exceto no Python, isso não funciona, ou melhor, não faz sentido. No Python, eu decido que tipo eu quero quando o uso. Eu quero uma corda? bem, se eu fizer algo assim:

print "The current value of foo is %s" % foo

Observe a %sstring -. Foo não é uma string, mas o %operador chama foo.___str___()e usa o resultado (supondo que ele exista). fooainda é um número inteiro, mas nós o tratamos como uma string, se queremos uma string. Se queremos uma bóia, então a tratamos como uma bóia. Em linguagens tipadas dinamicamente como Python, a notação húngara não faz sentido, porque não importa que tipo de coisa seja até você usá-la e se você precisar de um tipo específico, certifique-se de convertê-lo para esse tipo (por exemplo,float(foo) ) quando use-o.

Observe que linguagens dinâmicas como PHP não têm esse benefício - o PHP tenta fazer a "coisa certa" em segundo plano com base em um conjunto obscuro de regras que quase ninguém memorizou, o que geralmente resulta em desastres catastróficos inesperadamente. Nesse caso, algum tipo de mecanismo de nomeação, como $files_countou $file_name, pode ser útil.

Na minha opinião, a notação húngara é como sanguessugas. Talvez no passado eles fossem úteis, ou pelo menos parecessem úteis, mas hoje em dia é apenas uma digitação extra para não trazer muitos benefícios.


Interessante que o seu exemplo com .str () em Python não seja o resultado da linguagem ser dinâmica. Java, definitivamente não é uma linguagem dinâmica, faz a mesma coisa.
Dustman

C # também faz a mesma coisa, todas as classes nas implementos língua .ToString()de modo que tudo pode ser impresso
café eléctrica

5

O IDE deve transmitir essas informações úteis. O húngaro pode ter feito algum tipo (não muito, mas algum tipo) de sentido quando os IDE eram muito menos avançados.


4
Então, novamente, você não deve confiar no IDE, informando-o mais. Afinal, o código pode ser visto fora do IDE ...
TraumaPony /

5

Apps húngaro é grego para mim - em um bom sentido

Como engenheiro, não programador, imediatamente levei ao artigo de Joel sobre os méritos do Apps Hungarian: "Fazendo o código errado parecer errado" . Gosto do Apps Hungarian porque imita como a engenharia, a ciência e a matemática representam equações e fórmulas usando símbolos sub e super-script (como letras gregas, operadores matemáticos etc.). Veja um exemplo específico da Lei da Gravidade Universal de Newton : primeiro na notação matemática padrão e depois no pseudocódigo do Apps Hungarian:

Lei universal da gravidade de Newton para a Terra e Marte

frcGravityEarthMars = G * massEarth * massMars / norm(posEarth - posMars)

Na notação matemática, os símbolos mais importantes são aqueles que representam o tipo de informação armazenada na variável: força, massa, vetor de posição, etc. É exatamente isso que o Apps Hungarian está fazendo; está lhe dizendo o tipo de coisa armazenada na variável primeiro e, depois, entrando em detalhes - o código mais próximo pode chegar à notação matemática.

Uma digitação claramente forte pode resolver o exemplo de string segura versus insegura do ensaio de Joel, mas você não definiria tipos separados para vetores de posição e velocidade; ambos são matrizes duplas do tamanho três e qualquer coisa que você provavelmente faça em um pode se aplicar ao outro. Além disso, faz todo sentido concatenar posição e velocidade (para criar um vetor de estado) ou pegar seu produto escalar, mas provavelmente não o adiciona. Como a digitação permitiria os dois primeiros e proibiria o segundo, e como esse sistema se estenderia a todas as operações possíveis que você deseja proteger? A menos que você esteja disposto a codificar toda a matemática e física no seu sistema de digitação.

Além disso, muita engenharia é feita em linguagens de alto nível com tipos fracos, como o Matlab, ou em idiomas antigos, como o Fortran 77 ou o Ada.

Portanto, se você tem uma linguagem sofisticada, o IDE e o Apps Hungarian não ajudam a esquecê-la - muitas pessoas aparentemente têm. Mas para mim, pior do que um programador iniciante que trabalha em linguagens de tipo fraco ou dinâmico, posso escrever um código melhor mais rapidamente com o Apps Hungarian do que sem.


4

É incrivelmente redundante e inútil são os IDEs mais modernos, onde eles fazem um bom trabalho em tornar o tipo aparente.

Além disso - para mim - é apenas irritante ver intI, strUserName, etc. :)


3
Como o TraumaPony disse a Paul Batum, nem todo mundo vê o código no IDE.
Chris Charabaruk 23/09/08

4

Se sinto que informações úteis estão sendo transmitidas, por que não devo colocá-las exatamente onde estão disponíveis?

Então quem se importa com o que mais alguém pensa? Se você achar útil, use a notação.


Porque há apenas um de mim e um bilhão de outras pessoas que podem manter meu código mais tarde. Como todas essas pessoas estão no time (mas ainda não o conhecem), gostaria de ter uma ideia se elas me superam.
Dustman

4

Sou minha experiência, é ruim porque:

1 - então você quebra todo o código se precisar alterar o tipo de uma variável (ou seja, se precisar estender um número inteiro de 32 bits para um número inteiro de 64 bits);

2 - são informações inúteis, pois o tipo já está na declaração ou você usa uma linguagem dinâmica em que o tipo real não deve ser tão importante em primeiro lugar.

Além disso, com uma linguagem que aceita programação genérica (ou seja, funções em que o tipo de algumas variáveis ​​não é determinado quando você escreve a função) ou com sistema de digitação dinâmica (ou seja, quando o tipo nem sequer é determinado em tempo de compilação), como você nomeará seu variáveis? E a maioria dos idiomas modernos suporta um ou outro, mesmo que de forma restrita.


4

Em Making Wrong Code Wrong Code, de Joel Spolsky, ele explica que o que todo mundo considera Notação Húngara (que ele chama de Sistemas Húngaro) não é o que realmente deveria ser (o que ele chama de Apps Húngaro). Role para baixo até o cabeçalho Eu sou Hungria para ver esta discussão.

Basicamente, o sistema húngaro é inútil. Diz apenas a mesma coisa que o seu compilador e / ou IDE lhe dirá.

O Apps Hungarian diz o que a variável deve significar e pode realmente ser útil.


4

Eu sempre pensei que um prefixo ou dois no lugar certo não faria mal. Eu acho que se eu posso transmitir algo útil, como "Ei, isso é uma interface, não conte com comportamento específico" ali, como em IEnumerable, eu devo fazê-lo. Os comentários podem confundir muito mais as coisas do que apenas um símbolo de um ou dois caracteres.


1
Eu nunca peguei o ISomethingable. Se é um -able, isso implica interface de qualquer maneira. (Pelo menos em java)
tunaranch 29/11/08

4

É uma convenção útil para nomear controles em um formulário (btnOK, txtLastName etc.), se a lista de controles aparecer em uma lista suspensa em ordem alfabética no seu IDE.


4

I tendem a usar Hungarian Notation com controles de servidor ASP.NET apenas , caso contrário eu achar que é muito difícil descobrir quais são os controles que no formulário.

Pegue este snippet de código:

<asp:Label ID="lblFirstName" runat="server" Text="First Name" />
<asp:TextBox ID="txtFirstName" runat="server" />
<asp:RequiredFieldValidator ID="rfvFirstName" runat="server" ... />

Se alguém puder mostrar uma maneira melhor de ter esse conjunto de nomes de controle sem o húngaro, ficaria tentado a mudar para ele.


4

O artigo de Joel é ótimo, mas parece omitir um ponto importante:

O húngaro torna uma 'ideia' específica (tipo + nome do identificador) única, ou quase única, através da base de código - até mesmo uma base de código muito grande.

Isso é enorme para a manutenção do código. Isso significa que você pode usar a boa e velha pesquisa de texto de linha única (grep, findstr, 'find in all files') para encontrar TODAS as menções a essa 'ideia'.

Por que isso é importante quando temos IDE que sabem ler código? Porque eles não são muito bons nisso ainda. Isso é difícil de ver em uma pequena base de código, mas óbvia em uma grande - quando a 'idéia' pode ser mencionada em comentários, arquivos XML, scripts Perl e também em locais fora do controle de origem (documentos, wikis, bancos de dados de bugs).

Você precisa ter um pouco de cuidado, mesmo aqui - por exemplo, colar token em macros C / C ++ pode ocultar menções do identificador. Esses casos podem ser tratados com o uso de convenções de codificação e, de qualquer maneira, tendem a afetar apenas uma minoria dos identificadores na base de código.

PS Ao ponto de usar o sistema de tipos versus o húngaro - é melhor usar os dois. Você só precisa de um código errado para parecer errado se o compilador não o capturar. Existem muitos casos em que é inviável fazer o compilador capturá-lo. Mas onde for possível - sim, faça isso em vez disso!

Ao considerar a viabilidade, no entanto, considere os efeitos negativos da divisão de tipos. por exemplo, em C #, agrupar 'int' com um tipo não interno tem consequências enormes. Portanto, faz sentido em algumas situações, mas não em todas elas.


4

Desmistificando os benefícios da notação húngara

  • Ele fornece uma maneira de distinguir variáveis.

Se o tipo é tudo o que distingue um valor de outro, ele pode ser apenas para a conversão de um tipo em outro. Se você tiver o mesmo valor que está sendo convertido entre tipos, é provável que você esteja fazendo isso em uma função dedicada à conversão. (Eu já vi sobras VB6 húngaras usarem strings em todos os seus parâmetros de método simplesmente porque não conseguiram descobrir como desserializar um objeto JSON ou compreender adequadamente como declarar ou usar tipos anuláveis. ) Se você tiver duas variáveis ​​distinguidas apenas pelo Prefixo húngaro, e eles não são uma conversão de um para o outro, então você precisa elaborar sua intenção com eles.

  • Isso torna o código mais legível.

Descobri que a notação húngara torna as pessoas preguiçosas com seus nomes de variáveis. Eles têm algo para diferenciá-lo e não sentem necessidade de elaborar seu objetivo. Isso é o que você normalmente encontrará no código notável húngaro versus moderno: sSQL vs. groupSelectSql ( ou geralmente nenhum sSQL, porque eles deveriam estar usando o ORM que foi colocado pelos desenvolvedores anteriores. ), SValue vs. formCollectionValue ( ou geralmente também sem sValue, porque eles estão no MVC e devem estar usando seus recursos de ligação de modelo ), sType vs. publishSource etc.

Não pode ser legibilidade. Vejo mais sTemp1, sTemp2 ... sTempN de qualquer sobra VB6 húngara do que todos os outros juntos.

  • Previne erros.

Isso seria em virtude do número 2, que é falso.


3

Nas palavras do mestre:

http://www.joelonsoftware.com/articles/Wrong.html

Uma leitura interessante, como sempre.

Extratos:

"Alguém, em algum lugar, leu o artigo de Simonyi, onde ele usava a palavra" tipo "e pensava que ele queria dizer tipo, como classe, como em um sistema de tipos, como a verificação de tipo que o compilador faz. Ele não o fez. Ele explicou com muito cuidado exatamente o que ele quis dizer com a palavra "tipo", mas não ajudou. O dano foi causado ".

"Mas ainda há uma quantidade enorme de valor para o Apps Hungarian, na medida em que aumenta a disposição no código, o que facilita a leitura, gravação, depuração e manutenção, e, o mais importante, faz com que o código errado pareça errado."

Verifique se você tem algum tempo antes de ler o Joel On Software. :)


Não há tempo agora que eu tenho Stackoverflow. Eu acho que a mera associação de Spolsky com o projeto deve estar fazendo isso. :)
Dustman

3

Vários motivos:

  • Qualquer IDE moderno fornecerá o tipo de variável simplesmente passando o mouse sobre a variável.
  • A maioria dos nomes de tipo é longa (pense em HttpClientRequestProvider ) para ser razoavelmente usada como prefixo.
  • As informações de tipo não carregam o direito de informação, é apenas parafraseando a declaração de variável, em vez de descrevendo o propósito da variável (pense myInteger vs. pageSize ).

2

Eu não acho que todo mundo é furioso contra isso. Em idiomas sem tipos estáticos, é bastante útil. Definitivamente prefiro quando é usado para fornecer informações que ainda não estão no tipo. Como em C, char * szName diz que a variável se refere a uma sequência terminada nula - que não está implícita no char * - é claro, um typedef também ajudaria.

Joel tinha um ótimo artigo sobre o uso do húngaro para saber se uma variável era codificada em HTML ou não:

http://www.joelonsoftware.com/articles/Wrong.html

De qualquer forma, tenho tendência a não gostar do húngaro quando é usado para transmitir informações que eu já conheço.


Eu acho que a primeira frase pode desmentir as respostas nesta página.
Dustman

@ Dustman Bem, você não sabe que as strings C são terminadas em nulo? Vejo como seria útil quando a sequência não seria, mas isso é raro e, portanto, acho que o uso da convenção deve se limitar a esses casos.
Plumenator 10/03/12

Nem todo caractere * é uma string c terminada em nulo. O objetivo do húngaro é usá-lo para todas as variáveis, mesmo as que se enquadram no caso comum. Por fim, sinto-me como você - e, portanto, não o uso em C.
Lou Franco


2

Comecei a codificar praticamente na época em que a notação húngara foi inventada e a primeira vez em que fui forçado a usá-la em um projeto que eu odiava.

Depois de um tempo, percebi que, quando foi feito corretamente, realmente ajudou e hoje em dia eu amo.

Mas, como todas as coisas boas, tem que ser aprendido e compreendido, e fazê-lo adequadamente leva tempo.


1

A notação húngara foi abusada, principalmente pela Microsoft, levando a prefixos maiores que o nome da variável e mostrando que é bastante rígida, principalmente quando você altera os tipos (o infame lparam / wparam, de tipo / tamanho diferente no Win16, idêntico no Win32 )

Assim, devido a esse abuso e seu uso por M $, foi considerado inútil.

No meu trabalho, codificamos em Java, mas o fundador é do mundo MFC, portanto, usa estilo de código semelhante (chaves alinhadas, eu gosto disso !, maiúsculas nos nomes dos métodos, estou acostumado a isso, prefixo como m_ para os membros da classe (campos ), s_ para membros estáticos, etc.).

E eles disseram que todas as variáveis ​​devem ter um prefixo mostrando seu tipo (por exemplo, um BufferedReader é nomeado brData). O que mostrou ser uma péssima ideia, pois os tipos podem mudar, mas os nomes não seguem, ou os codificadores não são consistentes no uso desses prefixos (eu até vejo um Bufer, o Proxy, etc.!).

Pessoalmente, escolhi alguns prefixos que considero úteis, sendo o mais importante b prefixar variáveis ​​booleanas, pois são os únicos em que permito sintaxe como if (bVar) (sem uso de autocast de alguns valores como verdadeiro ou falso). Quando codifiquei em C, usei um prefixo para variáveis ​​alocadas com malloc, como lembrete de que deve ser liberado mais tarde. Etc.

Então, basicamente, não rejeito essa notação como um todo, mas aceitei o que parece adequado para minhas necessidades.
E, claro, ao contribuir para algum projeto (trabalho, código aberto), apenas uso as convenções em vigor!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.