Pesquisei no fórum, mas não consegui encontrar as respostas para evitar, apenas porque não é uma bala de prata. Portanto, não acho que essa pergunta seja uma duplicata.
Existe uma razão VÁLIDA para desaprender o sistema húngaro ao qual estou acostumado?
Até agora, vejo os seguintes benefícios em usá-lo:
- Nomenclatura consistente de variáveis
- Você vê o tipo sem pesquisar (o intellisense está inoperante / indexando metade do tempo, portanto ainda é um motivo válido)
- A semântica ainda pode ser compactada na segunda parte do nome
E seguintes desvantagens:
- Irrita algumas pessoas (não faço ideia do porquê)
- Se o tipo for alterado, o tipo pode não corresponder à nomeação da variável (não acho que seja um motivo válido, os tipos são alterados raramente e você "renomeia tudo")
Então por que:
vector<string> vecCityNames;
wstring strCity = L"abc";
//more code here
vecCityNames.push_back(strCity);
é pior que:
vector<string> cityNames;
wstring city = L"abc";
//more code here
cityNames.push_back(city);//Are we pushing back int on a queue? Float on a stack? Something else?
vectCityNames
servectStringCityNames
demais para o seu argumento consistente, e essa "pergunta" é mais um discurso retórico do que qualquer coisa, você já decidiu, isso deve ser encerrado.cityNames.push_back(city)
é bem claro. É uma lista de nomes de cidades e você está adicionando um.Respostas:
Eu costumava usá-lo (há muitos anos) e não o uso mais. A principal razão é que é supérfluo nas linguagens OO com digitação forte (C ++, Java) que, por acaso, usei a maior parte da minha carreira. Nesses idiomas, se eu definir bem meus tipos, o compilador poderá e imporá a segurança de tipos para mim. Portanto, qualquer prefixo de nomeação é apenas uma confusão que torna os nomes mais longos, dificultando a leitura e a pesquisa.
Em qualquer programa OO bem escrito, a maioria de suas variáveis são (referências a) tipos definidos pelo usuário. Se você os prefixar com a mesma tag geral (como
o
para "objeto"), você não obterá nenhum benefício com ela, apenas os inconvenientes. Se, no entanto, você os prefixar com tags específicas do tipo, você tenta encontrar abreviações diferentes para mil tipos diferentes com nomes frequentemente semelhantes * e lembre-se de alterá-las todas quando um tipo ou seu nome mudar (o que é não é raro em um programa bem conservado).Obviamente, isso não se aplica a idiomas não-OO e pode não se aplicar a idiomas de tipo fraco e / ou dinamicamente (não tenho experiência com eles, exceto C). Nem para editores / IDEs abaixo do ideal sem um IntelliSense utilizável (ou seu equivalente local). E este é apenas meus 2 centavos. Portanto, se a notação húngara funcionar para sua equipe e seu projeto, faça isso. O importante é concordar com isso (e também com um estilo de codificação consistente em geral) antes do início do projeto, e mantê-lo consistente o tempo todo.
* Apenas uma pequena lista do nosso projeto atual: temos
Charge
,ChargeBreakdown
,ChargeCalculator
,ChargeDAO
,ChargeDTO
,ChargeLineHelper
,ChargeMaps
,ChargePair
eChargeType
, entre outros. Além disso, também temosContract
s,Countrie
s,Checkout
s,Checkin
s ... e essa é apenas a letra C, em um projeto que provavelmente nem seria chamado de "tamanho razoável" pelo OP.Disclaimer: Na verdade, sou húngaro, então acredito que posso falar sobre esse assunto com autoridade ;-)
fonte
iPos
oufAmount
pode ser tolerável, mas tente trabalhar em uma base de código em que cada variável de objeto recebe um prefixo redundante de seis letras, informando apenas que é um "ponteiro para uma estrutura".char[]
mantidas por aStringBuilder
) e referências a instâncias que não podem ser mutadas, mas podem ser compartilhados com coisas que não os modificam (por exemplo, oschar[]
mantidos porString
, que podem ser compartilhados entre váriasString
instâncias). Ambos os campos são do mesmo tipochar[]
, mas contêm itens muito diferentes. Muitos bugs relacionados a mutabilidade são originados de ... #Por que é
std::vector<string> vecCityNames;
ruim?O problema com a notação húngara, como geralmente é usada, é que, se o perfil mostrar que os nomes das cidades devem ser mantidos em a
std::deque
, todos os nomes de variáveis referentes a um objeto desse tipo terão repentinamente um nome enganoso.Você irá renomear todas as suas variáveis? Você já tentou fazer isso em um grande projeto? Com a ajuda de Murphy (e o cara é incrivelmente útil lá), alguém em algum lugar certamente terá usado variáveis chamadas algo como
deqCityNames
, fazer suas alterações interromperem a construção, deixando você sentado por horas mexendo em código que, por meia década, ninguém se atreveu a olhar por medo de ser mordido por um animal venenoso.Pelo que sei, no entanto, da maneira como Charles Simonyi criou o húngaro, o prefixo estava denotando as variáveis uso semântico , e não o tipo sintático . Ou seja, o prefixo adequado para sua lista de nomes de cidades, independentemente do tipo em que é implementado, provavelmente seria
listCityNames
(oulstCityNames
, selist
não for suficientemente enigmático para você).Mas considero esse prefixo bastante supérfluo, porque o plural ("nomes") já indica que é um monte de cidades. Conclusão: quando você escolhe seus identificadores com cuidado, a notação húngara raramente é necessária. OTOH, a maneira como é comumente usada, está causando danos ao código a longo prazo.
fonte
typedef
é uma ferramenta muito desvalorizadavecCityNames
paradeqCityNames
algumas centenas de arquivos e faça a mesma coisa.Por qualquer motivo, as respostas existentes aqui parecem estar dançando a lógica da notação húngara, sem declará-la de imediato. A notação húngara é útil para adicionar informações de tipo (no sentido teórico do tipo ) quando seria difícil fazê-lo no próprio idioma . Por acaso, geralmente não é tão difícil usar o sistema de tipos C ++ ou Java de tal maneira que a notação húngara (como geralmente descrita) seja completamente supérflua, e é provavelmente isso que levou à reação contra ela - acrescenta trabalho ao programador manter essas anotações em todas as nossas variáveis variáveis, mas fornece pouco ou nenhum valor adicional (e pode até causar danos, pois o código parece mais confuso).
Por outro lado, se alguém restringir o uso da notação húngara para digitar informações (novamente, no sentido teórico do tipo ) que não sãonaturalmente encapsulado pelo idioma, pode ser muito útil. Por exemplo, C e C ++ passam referências de matriz como tipos de ponteiro, mas referências e ponteiros de matriz têm operações diferentes que devem ser executadas contra elas: matrizes podem ser indexadas além do primeiro elemento, enquanto ponteiros não. Essas são informações úteis que são perdidas para o sistema de tipos assim que uma matriz é passada para uma função como argumento. Assim, em nosso grupo, adotamos anotações de nome de variável nos códigos C e C ++ para distinguir se uma variável de ponteiro é realmente um ponteiro para um único elemento ou um ponteiro para uma matriz. A adoção desta convenção foi parcialmente responsável por uma grande redução na ocorrência de problemas de corrupção de memória em nossa base de códigos.
fonte
dw
vs.cb
). Não é que sua forma original seja menos útil nas linguagens OO: um índice ainda é um índice, mesmo se armazenado em um tipo de classe em vez de incorporado.A razão pela qual isso me incomoda é que é uma pequena lombada em cada identificador que diminui a velocidade da minha leitura visual do código. É mA, se você puder ler o texto em inglês como este.
fonte
O ódio é uma palavra muito forte, IMO. Você pode escrever seu código da maneira que desejar; Simplesmente prefiro não usar a notação húngara no meu próprio código e, se eu tiver uma opção, também prefiro não ter que lê-la ou trabalhar com ela no código de outras pessoas.
Você perguntou por que algumas pessoas acham a notação húngara irritante. Não posso falar pelos outros, mas os motivos que me incomodam são:
É feio. O húngaro usa nomes perfeitamente razoáveis e acrescenta o que equivale a um código. Depois de internalizar esse código, tenho certeza que faz todo o sentido, mas para os não iniciados, parece que alguém lançou o nome do manipulador de C ++ no meu código-fonte.
É redundante. A declaração de uma variável estabelece seu tipo; Não sinto a necessidade de repetir essa informação no nome da variável. Isso não é verdade em todos os idiomas: no Perl, por exemplo, sigilos como @ ou $ anexados ao nome da variável definem essencialmente o tipo da variável, para que você não tenha escolha a não ser usá-los.
Resolve um problema que não tenho. Métodos e funções não devem ser tão longos que você precisa procurar muito para encontrar a declaração de uma variável ou parâmetro local, e eles não devem envolver tantas variáveis que você tenha problemas para acompanhar o que é o quê. Declarar variáveis locais próximas ao código que as utiliza também ajuda nesse sentido. Os compiladores C do passado exigiam que todas as variáveis locais fossem declaradas no início da função, mas essa limitação foi removida há muito tempo.
Está incompleto. A notação húngara foi inventada para um idioma (BCPL) que não tinha um sistema de tipos e mais tarde foi amplamente utilizada em um idioma (C) que tinha um número bastante limitado de tipos nativos. IMO, ele não funciona bem com linguagens como C ++ ou Java que possuem sistemas de tipos extensos. Por que eu gostaria de usar um prefixo para indicar o tipo de uma variável nativa, como char [], mas não uma classe? Como alternativa, se eu começar a inventar prefixos como
vec
para classes, acabarei com uma grande hierarquia de prefixos paralela à minha hierarquia de classes. Se isso lhe agrada, você é bem-vindo; só de pensar nisso está me dando dor de cabeça.É ambíguo , pelo menos como eu o entendo. Qual é a diferença entre
szFoo
epszFoo
? O primeiro é uma sequência terminada com zero e o segundo é um ponteiro para uma sequência terminada com zero. Mas em C ou C ++, até onde eu sei, qualquer variável de string é efetivamente um ponteiro, então são iguais ou não? Qual devo usar? A resposta real realmente não importa - o ponto é que não consigo discernir a resposta usando a própria notação que deveria me ajudar a evitar esse tipo de pergunta. A declaração da variável, por outro lado, deve ser inequívoca porque é o que o compilador usa.Essas são as coisas que me incomodam na notação húngara. Mesmo como grupo, porém, não acho que expliquem completamente por que o húngaro foi amplamente abandonado. Aqui estão os três principais motivos pelos quais a maioria dos programadores não usa o húngaro:
Não há motivo convincente para usá-lo. Veja os itens 3 e 4 acima. Provavelmente eu poderia viver com os aborrecimentos se o húngaro oferecesse alguma grande vantagem em não usar o húngaro, mas não o vejo, e aparentemente a maioria das pessoas também não. Talvez a melhor coisa sobre o húngaro tenha sido a convenção amplamente usada e, se você se mantiver fiel ao uso padrão, poderá esperar razoavelmente que outros programadores com habilidades semelhantes possam entender a notação.
Maior influência de empresas que não são da Microsoft. Provavelmente, é justo dizer que a maioria dos programadores que adotaram a notação húngara o fez porque foi assim que a Microsoft escreveu o código e, muitas vezes, é mais fácil acompanhar o fluxo. Empresas como Google e Apple têm agora muito mais esferas de influência do que no passado, e mais programadores do que nunca estão adotando os estilos dessas empresas e de outras que em geral evitam o húngaro. (É justo ressaltar que você ainda vê alguns remanescentes, por exemplo, o Google e a Apple costumam usar um prefixo 'k' para nomes constantes.)
A própria Microsoft abandonou o húngaro. Se você verificar a seção de convenções gerais de nomenclatura da Microsoft em suas diretrizes de codificação, verá que está escrito em negrito: não use a notação húngara.
Portanto, um motivo válido para parar de usar a notação húngara é:
A popularidade da notação húngara diminuiu a ponto de a convenção não ser mais útil. Atualmente, muito menos programadores usam ou mesmo entendem o húngaro, e a convenção é, portanto, muito menos eficaz em transmitir as informações que deveria. Se você achar que é uma maneira útil de escrever código em seus próprios projetos pessoais, há poucas razões para parar. No entanto, se você estiver escrevendo um código como parte de uma equipe que não usa o húngaro, pode se tornar uma barreira entre você e o restante da equipe, em vez de uma estratégia de comunicação bem-sucedida.
fonte
szFoo
epszFoo
"? Um échar*
, o outrochar**
, levei 0,25 segundos para dizer a diferença. Tente superar isso com o Intellisense.pnFoo
provavelmenteint*
não seria ,int**
então você precisa saber que issosz
também significa um ponteiro. Tenho certeza de que não é um grande problema para o número limitado de tipos que estabeleceram prefixos húngaros, mas em qualquer projeto grande o número de tipos definidos está na casa dos milhares. Não conheço o Intellisense, mas os IDEs melhoraram constantemente nos últimos 25 anos e espero que essa tendência continue.Se eu citar todas as minhas variáveis após os personagens de Os Simpsons, isso também é consistente, mas é um benefício?
Esta é a única razão válida, com base na fraqueza de uma ferramenta específica ...
Isso não é um benefício; você está apenas reivindicando a ausência de uma desvantagem ( maciça ).
fonte
O IDE me diz trivialmente qual é o tipo de uma variável quando o mouse sobre ela. Então, por que se preocupar em duplicar essas informações? Fundamentalmente, a notação húngara em sistemas é uma violação do DRY, com todas as armadilhas associadas a ele. Quando essas informações são trivialmente acessíveis em um ambiente moderno, não há razão para pagar esse preço.
A consistência não é uma vantagem em si mesma. Não nomeá-los com o tipo também é consistente. Você só teria inconsistência se apenas algumas variáveis tivessem seus tipos no nome. E colocar a semântica na segunda parte é simplesmente "Bem, não é tão ruim assim.", Todo mundo usa o nome inteiro para semântica. Você não tem nenhuma vantagem real listada.
fonte
Outro ponto das formas tradicionais de notação húngara é que elas geralmente são prefixos. existem 2 problemas aqui:
1) Um leitor humano geralmente gostaria primeiro da informação mais importante; na maioria das formas de húngaro, a informação codificada é indiscutivelmente menos importante do que o próprio nome.
2) Os prefixos efetuam a classificação lexical; portanto, se você usará um prefixo para denotar interfaces ou classes e seu IDE fornecer uma lista classificada dessas classes / interfaces relacionadas, elas serão separadas nesta lista.
fonte
Claramente, isso se resume a opiniões, então será difícil trabalhar com fatos aqui. Pessoalmente, acho que o argumento para a notação húngara é um pouco tênue em linguagens orientadas a objetos com tipos fortes. Na minha experiência, os aplicativos OO tendem a lidar com a complexidade, mantendo as classes coerentes e concisas, e o mesmo pode ser dito sobre as funções. Isso significa que todas as outras coisas são iguais, você acaba com:
Agora, se você quiser usar a notação húngara, terá que decidir se deve aplicá-la em geral ou apenas para certos tipos e classes privilegiadas (como as classes principais da biblioteca). O último não faz sentido para mim, e o primeiro leva ao "labirinto de tentar encontrar abreviações diferentes para mil tipos diferentes" a que Péter Török se referia. Isso significa que há uma sobrecarga significativa na manutenção de listas de abreviações e, geralmente, "nomes de variáveis consistentes" sai pela janela.
O segundo ponto sobre métodos mais curtos significa que, na maioria dos casos, você não precisará passar por centenas de linhas de código para verificar o tipo de variável. Nomeando variáveis ligeiramente mais cuidado eliminaria algumas das suas outras perguntas - por exemplo,
cityName
contra apenascity
. Eu espero quecityName
não seja um carro alegórico :)Quanto ao motivo pelo qual isso incomoda as pessoas - mais uma vez, isso provavelmente está acostumado a isso ou não. Mas como alguém que não está acostumado a isso, posso lhe dizer que o uso da notação húngara interrompe o fluxo de código para meus olhos, dificultando a leitura rápida. Para resumir, eu não estou dizendo que não tem nenhum mérito (embora eu não tenha discutido algumas das suas desvantagens, em termos de refatoração, etc), eu estou dizendo que o esforço não vale a pena, por fortemente tipado, linguagens OO.
fonte
Eu não sei no contexto de C ++, mas no mundo Java / C # eu preferiria ter nomes significativos que transmitam uma linguagem ou contexto de domínio do que me dizer que
strFirstName
é uma String; deve ser óbvio que é uma string ou o nome precisa ser refatorado para transmitir uma melhor intenção. Se você precisar de um prefixo para saber o tipo com o qual está trabalhando, eu diria que sua nomeação é inconsistente, não é descritiva o suficiente ou é totalmente errada. Nas línguas modernas, eu sempre prefiro nomes mais longos que não deixam ambiguidade do que nomes vagos ou ambíguos.A única vez em que uso o húngaro é nos controles do ASP.NET, e isso é mais do que IA) não precisa digitar algo muito longo como
CustomerFirstNameTextBox
versustxtCustomerFirstName
eb) Então o Intellisense classifica todos os tipos de controle. Eu me sinto "sujo", mesmo fazendo isso, porém, ainda tenho que encontrar uma maneira melhor.fonte
Meh - é realmente tudo sobre preferências pessoais, por mais que se tente racionalizar suas escolhas. Pessoalmente, adiro à regra "When in Rome ..." e uso o húngaro em código que chama muito a API do Windows. Para código independente de plataforma, eu costumo seguir o estilo C ++ Standard Library.
fonte
A resposta está nesta pergunta: Por favor, diga-me como nomear as seguintes variáveis:
Adicione a essas cadeias constantes, ponteiro para elas e ponteiros constantes para elas.
fonte
szFoo
,wczFoo
,strFoo
,(w)strFoo
,strFoo
,bstrFoo
,bstrFoo
Não gosto muito da forma de notação húngara que você descreve. O motivo? Não serve nenhum ponto 90% do tempo.
Por exemplo, um pouco de código (equivalente em C ++. Realmente escrito em Delphi) de um projeto legado que sou obrigado a suportar:
... pRecord é uma variável, do tipo TRecordList.
TRecordList *pRecords[10];
É uma classe que consiste em um orioerty chamado FooMember que aponta para fFooMember ... ou mFooMember, dependendo se é um "campo" ou um "membro" (dica: eles são a mesma coisa)
Problemas?
fFooMember
pode ser algo como FooMember_, porque sempre o acessaremos através da propriedade pública FooMember. pRecords? É bastante óbvio que é um indicador do fato de que você desrefere isso por todo o lugar. TRecordList? Quando você pode confundir um nome de tipo e um objeto desse tipo? O compilador gritará com você e os tipos são usados em quase nenhum lugar em que os objetos estão (exceto para propriedades / métodos estáticos)Agora, há um lugar onde eu uso a notação húngara. É quando se lida com muitas variáveis da interface do usuário que teriam o mesmo nome que outras variáveis da interface do usuário ou variáveis regulares.
Por exemplo, se eu tivesse um formulário para o seu primeiro nome.
Eu teria uma classe chamada FirstNameForm. Dentro dele, lblFirstName e txtFirstName para o rótulo e a caixa de texto, respectivamente. E uma propriedade pública FirstName para obter e definir o nome na caixa de texto.
Isso também pode ser resolvido usando FirstNameLabel e FirstNameTextBox, mas acho que demora muito para digitar. Especialmente com algo como GenderDropDownList e tal.
Então, basicamente, a notação húngara é, na melhor das hipóteses, irritante no nível sistemático e, no pior dos casos, prejudicial (já que as outras respostas dão problemas sobre refatoração e consistência).
fonte