¿Por qué no debería usar "notación húngara"?


122

Sé a qué se refiere húngaro: dar información sobre una variable, parámetro o tipo como prefijo de su nombre. Todo el mundo parece estar en contra de ello, aunque en algunos casos sea una buena idea. Si siento que se está impartiendo información útil, ¿por qué no debería ponerla allí donde está disponible?

Ver también: ¿La gente usa las convenciones de nomenclatura húngaras en el mundo real?


Respuestas:


174

La mayoría de las personas usan la notación húngara de manera incorrecta y obtienen resultados incorrectos.

Lea este excelente artículo de Joel Spolsky: Hacer que el código incorrecto parezca incorrecto .

En resumen, la notación húngara donde prefijas tus nombres de variables con su type(cadena) (sistemas húngaros) es mala porque es inútil.

La notación húngara, tal como fue diseñada por su autor, donde prefijas el nombre de la variable con su kind(usando el ejemplo de Joel: cadena segura o cadena no segura), las llamadas aplicaciones húngaras tienen sus usos y siguen siendo valiosas.


55
Buen enlace, un buen resumen de lo que hay detrás del enlace, y sin fanatismo. Excelente.
Dustman

12
Tenga en cuenta que el ejemplo de Joels está en VBScript, un lenguaje que durante mucho tiempo no tuvo clases definidas por el usuario. En un lenguaje OO, simplemente crearías un tipo HtmlEncodedString y harías que el método Write solo aceptara eso. Las "aplicaciones húngaras" solo son útiles en idiomas sin tipos definidos por el usuario.
JacquesB

44
Microsoft es conocido por su mal uso pasado de la notación húngara. Anteponer información de tipo a identificadores no solo es inútil, sino que en realidad puede hacer daño. Primero, la legibilidad es menos fluida. En segundo lugar, en los idiomas que admiten el polimorfismo o el tipeo de pato, se pasa la información incorrecta.
wilhelmtell

9
Todavía me gusta usar la notación húngara si estoy haciendo un desarrollo C directo con un IDE anterior ... de esa manera sé que no hay problemas de conversión de tipos.
Beep beep

3
@Krumia: Esto normalmente se evitaría teniendo nombres descriptivos de variables en primer lugar. Pero si quiere estar seguro, sería mucho más seguro crear tipos distintos (por ejemplo, estructuras) para longitudes, pesos, etc. y utilizar la sobrecarga del operador para garantizar que solo sean posibles operaciones válidas.
JacquesB

277

vUtilizar adj Nunation en húngaro v hace que leer ncode ncode sea difícil.


101
Buena analogía, aunque un poco injusta. Compare: vUtilizando adjHungarian nNotation vMakes nReading nCode adjDifficult.
Chris Noe

27
En esa oración, tanto el uso como la lectura son gerundios. Pero entiendo lo que estabas diciendo ...
chimpancé

28
@chimp: eso hace que las cosas sean aún más obvias. ahora que ha encontrado un error en el tipo, ¿va a cambiar el nombre de todas las referencias o dejarlas como están, proporcionando información errónea? pierdes de cualquier manera. pero, por supuesto, esta es la forma INCORRECTA de aplicar la notación húngara.
wilhelmtell

1
@ Chris Noe: para ciertos estilos de lectura (analice el prefijo y el sufijo con una mirada al medio), su ejemplo solo empeora las cosas. Veo "vUsing" y escucho "voosing" en mi cabeza.
Bob Cross

3
@ Jon: si tiene un nombre de variable que no revela por completo lo que representa, entonces, por supuesto, el enfoque debería ser cambiar el nombre a algo más descriptivo (y la notación húngara no es una mejora, en el muy, muy el mejor caso es arreglar el síntoma, no resolver el problema).
hlovdal

104

Joel está equivocado, y aquí está el por qué.

Esa información de "aplicación" de la que está hablando debe estar codificada en el sistema de tipos . No debe depender de voltear nombres de variables para asegurarse de no pasar datos inseguros a funciones que requieren datos seguros. Debería convertirlo en un error de tipo, de modo que sea imposible hacerlo. Cualquier dato inseguro debe tener un tipo marcado como inseguro, de modo que simplemente no se pueda pasar a una función segura. Para convertir de inseguro a seguro debe requerir procesamiento con algún tipo de función de desinfección.

Muchas de las cosas de las que Joel habla como "tipos" no son tipos; son, de hecho, tipos.

Sin embargo, lo que le falta a la mayoría de los idiomas es un sistema de tipos que sea lo suficientemente expresivo como para imponer este tipo de distinciones. Por ejemplo, si C tuviera una especie de "typedef fuerte" (donde el nombre typedef tenía todas las operaciones del tipo base, pero no era convertible), muchos de estos problemas desaparecerían. Por ejemplo, si pudiera decir que strong typedef std::string unsafe_string;para introducir un nuevo tipo unsafe_stringque no se podría convertir en una cadena estándar std :: (y que podría participar en la resolución de sobrecarga, etc., etc.), no necesitaríamos prefijos tontos.

Entonces, la afirmación central de que el húngaro es para cosas que no son tipos está mal. Se está utilizando para información de tipo. Información de tipo más rica que la información de tipo C tradicional, ciertamente; Es información de tipo que codifica algún tipo de detalle semántico para indicar el propósito de los objetos. Pero todavía es información de tipo, y la solución adecuada siempre ha sido codificarla en el sistema de tipos. Codificarlo en el sistema de tipos es, de lejos, la mejor manera de obtener la validación y la aplicación adecuadas de las reglas. Los nombres de las variables simplemente no cortan la mostaza.

En otras palabras, el objetivo no debe ser "hacer que el código incorrecto parezca incorrecto para el desarrollador". Debería ser "hacer que el código incorrecto parezca incorrecto para el compilador ".


30
La intención de la variable debe codificarse dentro del tipo de la variable, no dejarse a algo tan frágil como un esquema de nombres.
DrPizza

3
Me encantaría convertirlo también en el trabajo del compilador / intérprete, pero eso generaría una gran sobrecarga para los lenguajes dinámicos (Python, Ruby, PHP o Javascript).
demasiado php

22
"Sin embargo, lo que le falta a la mayoría de los idiomas es un sistema de tipos que sea lo suficientemente expresivo como para imponer este tipo de distinciones" Y ahí está el problema. AppsHungarian es un método pragmático para resaltar problemas al usar estos lenguajes de manera obvia para que los programadores vean el código, en lugar de examinar los informes de errores.
Neil Trodden

66
@DrPizza: Creo que te has perdido uno de los puntos muy importantes que Joel está haciendo al defender Apps Hungarian: esta notación es solo una compensación muy pragmática . Hacer que el compilador sea capaz de ver "código incorrecto" es un gran objetivo, pero ¿siempre vale la pena?
Yarik

44
@DrPizza: Joel is wrongy What most languages lack, however, is a type system that's expressive enough to enforce these kind of distinctions.tanto, ya que la mayoría de los idiomas no tienen la suficiente expresividad para hacer cumplir este tipo de distinciones, Joel es correcto. ¿Correcto?
sampathsris

46

Creo que desorden masivamente el código fuente.

Tampoco te gana mucho en un lenguaje fuertemente tipado. Si realiza alguna forma de tontería no coincidente, el compilador le informará al respecto.


Guau. 90 repeticiones en 15 minutos. Buena llamada.
Dustman

2
Si lo usa para escribir, sí, es inútil. Es útil para transmitir otra información.
Lou Franco

12
@Lou, exactamente, personalmente, almaceno un historial de revisiones en mis nombres de variables: string firstName_wasName_wasNameID_wasSweetCupinCakes
Shog9

@nsanders: intente usar el compilador para verificar si utilizó las mismas unidades de medida cuando ambos tipos de variables son enteros.
Igor Levicki

1
@ Shog9: Creo que no entendiste la notación húngara de Apps. Se trata más de sFirstName vs unFirstName (seguro vs inseguro, no saneado), de esta manera usted sabe algo más al respecto. Aún así, creo que en lenguajes estáticos es mejor subtipar String para hacer UnsafeString y SafeString y solo permitir que se produzca SafeString. La convención está bien, pero (más a menudo) los requisitos de compilación son mejores.
kgadek

28

La notación húngara solo tiene sentido en idiomas sin tipos definidos por el usuario . En un lenguaje funcional u OO moderno, codificaría información sobre el "tipo" de valor en el tipo de datos o clase en lugar de en el nombre de la variable.

Varias respuestas hacen referencia al artículo de Joels . Sin embargo, tenga en cuenta que su ejemplo está en VBScript, que no admitía clases definidas por el usuario (al menos durante mucho tiempo). En un lenguaje con tipos definidos por el usuario, resolvería el mismo problema creando un tipo HtmlEncodedString y luego dejaría que el método Write solo aceptara eso. En un lenguaje de tipo estático, el compilador detectará cualquier error de codificación, de forma dinámica obtendrá una excepción de tiempo de ejecución, pero en cualquier caso está protegido contra la escritura de cadenas no codificadas. Las anotaciones húngaras solo convierten al programador en un verificador de tipo humano, con el tipo de trabajo que normalmente se maneja mejor con el software.

Joel distingue entre "sistemas húngaros" y "aplicaciones húngaras", donde "sistemas húngaros" codifica los tipos integrados como int, float, etc., y "aplicaciones húngaras" codifica "tipos", que es metainformación de nivel superior acerca de la variable entre el tipo de máquina, en un OO o lenguaje funcional moderno, puede crear tipos definidos por el usuario, por lo que no hay distinción entre tipo y "kind" en este sentido, ambos pueden ser representados por el sistema de tipos y "apps" el húngaro es tan redundante como los "sistemas" húngaros.

Entonces, para responder a su pregunta: los sistemas húngaros solo serían útiles en un lenguaje inseguro y de tipo débil donde, por ejemplo, asignar un valor flotante a una variable int bloqueará el sistema. La notación húngara se inventó específicamente en los años sesenta para su uso en BCPL , un lenguaje de nivel bastante bajo que no hacía ninguna verificación de tipo. No creo que ningún lenguaje de uso general hoy tenga este problema, pero la notación vivió como una especie de programación de culto de carga .

Las aplicaciones húngaras tendrán sentido si está trabajando con un idioma sin tipos definidos por el usuario, como VBScript heredado o versiones anteriores de VB. Quizás también las primeras versiones de Perl y PHP. Nuevamente, usarlo en un idioma moderno es puro culto de carga.

En cualquier otro idioma, el húngaro es feo, redundante y frágil. Repite información ya conocida del sistema de tipos, y no debe repetirse usted mismo . Use un nombre descriptivo para la variable que describe la intención de esta instancia específica del tipo. Utilice el sistema de tipos para codificar invariantes y metainformación sobre "tipos" o "clases" de variables, es decir. tipos.

El punto general del artículo de Joels - hacer que el código incorrecto se vea mal - es un muy buen principio. Sin embargo, una protección aún mejor contra errores es, cuando sea posible, tener un código incorrecto para que el compilador lo detecte automáticamente.


Los idiomas con tipos definidos por el usuario no siempre hacen práctico el uso de tipos en lugar de "tipos". Considere los prefijos "c", "d", "ix" de las aplicaciones húngaras de Joel. ¿Utiliza tipos enteros personalizados para esos, en todos los idiomas modernos? No lo creo. Debido a que los idiomas modernos aún no tienen tipos enteros personalizados para índices, recuentos y diferencias entre dos números. Mientras sigamos usando entradas de vainilla, Apps Hungarian será no redundante y útil.
Eldritch Conundrum

27

Siempre uso la notación húngara para todos mis proyectos. Me resulta realmente útil cuando estoy tratando con cientos de nombres de identificadores diferentes.

Por ejemplo, cuando llamo a una función que requiere una cadena, puedo escribir 's' y presionar espacio de control y mi IDE me mostrará exactamente los nombres de las variables con el prefijo 's'.

Otra ventaja, cuando prefijo u para unsigned yi para ints firmados, veo de inmediato dónde estoy mezclando firmado y sin firmar de formas potencialmente peligrosas.

No puedo recordar la cantidad de veces que, en una enorme base de código de línea de 75000, los errores fueron causados ​​(por mí y por otros también) debido a nombrar variables locales de la misma manera que las variables miembro existentes de esa clase. Desde entonces, siempre prefijo miembros con 'm_'

Es una cuestión de gusto y experiencia. No lo golpees hasta que lo hayas probado.


1
La codificación de la firma en nombres de variables es excelente cuando el fragmento de código en realidad trata de la firma. Usar eso como una excusa para hacer cumplir la convención para todas las variables es solo domatismo en mi humilde opinión.
Plumenator

Sin embargo, tiene un buen punto con las variables miembro. Pero en lenguajes como Python, donde te obligan a calificar a los miembros con el self / este objeto, es discutible.
Plumenator

Es solo un truco para ayudar a la productividad. Al igual que el autocompletado IDE. No hay nada fundamentalmente malo en ello. Creo que los codificadores experimentados deben poder usar su propio estilo. Obligar a cualquiera a elegir un estilo determinado es malo. Ahora trabajo como desarrollador único, pero no impondría un estilo a nadie con quien trabajé a menos que carecieran de un estilo consistente en primer lugar.
rep_movsd

Entonces, estás usando una convención de nomenclatura para filtrar las variables, ¿eh? Debo estar de acuerdo en que es un poco inteligente . :-) Sin embargo, la forma en que estoy conectado, el punto de anclaje (o criterio de filtro, si lo desea) es siempre la semántica para mí. Raramente el tipo (a menos que sea la semántica). Espero que tenga sentido. TL; DR: Todavía me apegaría a nombrar variables de acuerdo con lo que representan que cómo están representadas.
Plumenator

1
Voté esto en ese entonces ya que estaba a favor del húngaro. Ahora lo lamento, y nunca volvería a prefijar algo a una variable ..
nawfal

22

Olvida la razón número uno para incluir esta información. No tiene nada que ver contigo, el programador. Tiene todo que ver con la persona que viene por el camino 2 o 3 años después de que abandonas la empresa que tiene que leer esas cosas.

Sí, un IDE identificará rápidamente los tipos por usted. Sin embargo, cuando está leyendo algunos lotes largos de código de 'reglas de negocio', es bueno no tener que detenerse en cada variable para averiguar de qué tipo es. Cuando veo cosas como strUserID, intProduct o guiProductID, facilita mucho el tiempo de ' aceleración '.

Estoy de acuerdo en que la EM fue demasiado lejos con algunas de sus convenciones de nomenclatura; lo clasifico en el montón "demasiado bueno".

Las convenciones de nomenclatura son buenas, siempre que las cumpla. He revisado suficiente código antiguo que me obligaba a volver constantemente a mirar las definiciones de tantas variables con nombres similares que presiono "camel case" (como se llamaba en un trabajo anterior). En este momento estoy en un trabajo que tiene miles de líneas de código ASP clásico completamente sin comentar con VBScript y es una pesadilla tratar de resolver las cosas.


Como usuario de VIM (sin IDE, sin resaltar, sin pasar el cursor sobre qué decir), no entiendo este argumento en absoluto. Naturalmente, entiendo que una variable llamada name es una cadena, y una variable llamada i o count es un int. ¿Realmente se necesita sName e iCount? ¿Cómo realmente ayuda? Yo diría que su ejemplo de identificación de producto es un caso especial, y tal vez allí estaría bien. Pero incluso entonces, ser coherente y representar ID de productos con ints o strings en todas partes sería una solución mucho mejor, ¿no? Todo el asunto de los nombres parece una evasión.
MrFox

66
Es por consistencia. Sí, "nombre" implica inherentemente una cadena. Pero, ¿qué presumirías que es "userid"? Un GUID? ¿Cuerda? ¿Entero? Incluso algo como "acctno" podría tener un valor de 42 o "23X". La documentación es lo suficientemente escasa en la mayoría de los códigos. Este estándar ayuda un poco al programador de mantenimiento.
David

1
@David Estoy totalmente de acuerdo con su respuesta: saber de un vistazo la intención de la variable es la razón por la que prefiero el prefijo también, más aún en un lenguaje dinámico como JS.
Daniel Sokolowski

10

No es necesario agregar caracteres crípticos al comienzo de cada nombre de variable y muestra que el nombre de la variable por sí solo no es lo suficientemente descriptivo. La mayoría de los idiomas requieren el tipo de variable en la declaración de todos modos, por lo que la información ya está disponible.

También existe la situación en la que, durante el mantenimiento, un tipo variable debe cambiar. Ejemplo: si una variable declarada como "uint_16 u16foo" necesita convertirse en un 64-bit sin signo, ocurrirá una de dos cosas:

  1. Revisará y cambiará el nombre de cada variable (asegurándose de no manipular ninguna variable no relacionada con el mismo nombre), o
  2. Simplemente cambie el tipo y no cambie el nombre, lo que solo causará confusión.

9

Joel Spolsky escribió una buena publicación de blog sobre esto. http://www.joelonsoftware.com/articles/Wrong.html Básicamente se trata de no hacer que su código sea más difícil de leer cuando un IDE decente le dirá que desea escribir la variable si no lo recuerda. Además, si hace que su código esté suficientemente compartimentado, no tiene que recordar qué declararon las variables como tres páginas hacia arriba.


9

No es el alcance más importante que el tipo en estos días, por ejemplo

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

Con las técnicas modernas de refactorización de código antiguo, la búsqueda y el reemplazo de un símbolo porque cambió su tipo es tedioso, el compilador detectará los cambios de tipo, pero a menudo no detectará el uso incorrecto del alcance, las convenciones de nomenclatura sensatas ayudan aquí.


Por otra parte, el código probablemente no debería depender tanto del alcance. :-)
Plumenator

8

No hay ninguna razón por la que no debas hacer un uso correcto de la notación húngara. Su impopularidad se debe a una reacción duradera contra el mal uso de la notación húngara, especialmente en las API de Windows.

En los viejos tiempos, antes de que existiera algo parecido a un IDE para DOS (es probable que no tuviera suficiente memoria libre para ejecutar el compilador en Windows, por lo que su desarrollo se realizó en DOS), no recibió ninguna ayuda de colocando el mouse sobre un nombre de variable. (Suponiendo que tuviera un mouse.) Con lo que sí tuvo que lidiar fueron las funciones de devolución de llamada de eventos en las que todo se le pasó como int de 16 bits (WORD) o int de 32 bits (WORD LARGO). Luego tuvo que convertir esos parámetros a los tipos apropiados para el tipo de evento dado. En efecto, gran parte de la API era prácticamente sin tipo.

El resultado, una API con nombres de parámetros como estos:

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

Tenga en cuenta que los nombres wParam y lParam, aunque bastante horribles, no son realmente peores que nombrarlos param1 y param2.

Para empeorar las cosas, Windows 3.0 / 3.1 tenía dos tipos de punteros, cerca y lejos. Entonces, por ejemplo, el valor de retorno de la función de administración de memoria LocalLock era un PVOID, pero el valor de retorno de GlobalLock era un LPVOID (con la 'L' por mucho tiempo). Que la notación horrible luego se extiende de manera que un l ong p ointer cadena fue prefijado lp , para distinguirla de una cadena que simplemente había sido malloc'd.

No sorprende que haya una reacción violenta contra este tipo de cosas.


6

La notación húngara puede ser útil en idiomas sin verificación de tipo en tiempo de compilación, ya que permitiría al desarrollador recordar rápidamente cómo se usa la variable en particular. No hace nada por rendimiento o comportamiento. Se supone que mejora la legibilidad del código y es principalmente una cuestión de gusto y estilo de codificación. Por esta misma razón, muchos desarrolladores lo critican: no todos tienen el mismo cableado en el cerebro.

Para los lenguajes de verificación de tipos en tiempo de compilación es en su mayoría inútil: desplazarse hacia arriba unas pocas líneas debería revelar la declaración y, por lo tanto, escribir. Si sus variables globales o su bloque de código se extiende por más de una pantalla, tiene serios problemas de diseño y reutilización. Por lo tanto, una de las críticas es que la notación húngara permite a los desarrolladores tener un mal diseño y salirse con la suya fácilmente. Esta es probablemente una de las razones de odio.

Por otro lado, puede haber casos en los que incluso los lenguajes de verificación de tipos en tiempo de compilación se beneficiarían de la notación húngara: punteros nulos o HANDLE en la API win32. Esto ofusca el tipo de datos real, y puede ser conveniente utilizar la notación húngara allí. Sin embargo, si uno puede conocer el tipo de datos en el momento de la compilación, ¿por qué no utilizar el tipo de datos apropiado?

En general, no hay razones difíciles para no usar la notación húngara. Es una cuestión de gustos, políticas y estilo de codificación.


6

Como programador de Python, la notación húngara se desmorona bastante rápido. En Python, no me importa si algo es una cadena, me importa si puede actuar como una cadena (es decir, si tiene un ___str___()método que devuelve una cadena).

Por ejemplo, digamos que tenemos foo como un entero, 12

foo = 12

La notación húngara nos dice que deberíamos llamar a eso iFoo o algo así, para denotar que es un número entero, para que más adelante sepamos qué es. Excepto en Python, eso no funciona, o más bien, no tiene sentido. En Python, decido qué tipo quiero cuando lo uso. ¿Quiero una cuerda? bueno si hago algo como esto:

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

Tenga en cuenta la %scadena. Foo no es una cadena, pero el %operador llamará foo.___str___()y usará el resultado (suponiendo que exista). foosigue siendo un número entero, pero lo tratamos como una cadena si queremos una cadena. Si queremos un flotador, lo tratamos como un flotador. En lenguajes de tipo dinámico como Python, la notación húngara no tiene sentido, porque no importa de qué tipo sea algo hasta que lo uses, y si necesitas un tipo específico, solo asegúrate de convertirlo en ese tipo (por ejemplo float(foo)) cuando úsalo.

Tenga en cuenta que los lenguajes dinámicos como PHP no tienen este beneficio: PHP intenta hacer "lo correcto" en segundo plano basándose en un oscuro conjunto de reglas que casi nadie ha memorizado, lo que a menudo resulta en desastres catastróficos inesperadamente. En este caso, algún tipo de mecanismo de denominación, como $files_counto $file_name, puede ser útil.

En mi opinión, la notación húngara es como sanguijuelas. Quizás en el pasado fueron útiles, o al menos parecían útiles, pero hoy en día es solo una gran cantidad de tipeo adicional para no muchos beneficios.


Es interesante que su ejemplo con .str () en Python no sea el resultado de que el lenguaje sea dinámico. Java, definitivamente no es un lenguaje dinámico, hace lo mismo.
Dustman

C # también hace lo mismo, cada clase en el lenguaje se implementa .ToString()para que todo se pueda imprimir
Electric Coffee

5

El IDE debería impartir esa información útil. El húngaro podría haber tenido algún tipo de sentido (no mucho, pero sí mucho) cuando los IDE estaban mucho menos avanzados.


44
Por otra parte, no debe confiar en que el IDE le diga más. Después de todo, el código se puede ver fuera del IDE ...
TraumaPony

5

Apps Hungarian es griego para mí, en el buen sentido

Como ingeniero, no como programador, inmediatamente llevé al artículo de Joel sobre los méritos de las aplicaciones húngaras: "Hacer que el código incorrecto parezca incorrecto" . Me gusta las aplicaciones húngaras porque imita cómo la ingeniería, la ciencia y las matemáticas representan ecuaciones y fórmulas que usan símbolos sub y scripts (como letras griegas, operadores matemáticos, etc.). Tomemos un ejemplo particular de la Ley de la gravedad universal de Newton : primero en notación matemática estándar y luego en pseudocódigo húngaro de aplicaciones:

Ley de gravedad universal de Newton para la Tierra y Marte

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

En la notación matemática, los símbolos más destacados son aquellos que representan el tipo de información almacenada en la variable: fuerza, masa, vector de posición, etc. Los subíndices juegan el segundo violín para aclarar: ¿posición de qué? Esto es exactamente lo que está haciendo Apps Hungarian; te está diciendo primero el tipo de cosas almacenadas en la variable y luego entrando en detalles: sobre el código más cercano que puede llegar a la notación matemática.

Claramente, la escritura fuerte puede resolver el ejemplo de cadena segura frente a insegura del ensayo de Joel, pero no definiría tipos separados para los vectores de posición y velocidad; ambos son matrices dobles de tamaño tres y cualquier cosa que probablemente le hagas a uno podría aplicarse al otro. Además, tiene mucho sentido concatenar la posición y la velocidad (para hacer un vector de estado) o tomar su producto de puntos, pero probablemente no para agregarlos. ¿Cómo permitiría la mecanografía los dos primeros y prohibiría el segundo, y cómo se extendería dicho sistema a todas las operaciones posibles que desee proteger? A menos que esté dispuesto a codificar todas las matemáticas y la física en su sistema de escritura.

Además de todo eso, mucha ingeniería se realiza en lenguajes de alto nivel débilmente tipados como Matlab, o los antiguos como Fortran 77 o Ada.

Entonces, si tienes un lenguaje sofisticado y el IDE y las aplicaciones húngaras no te ayudan, entonces olvídalo, aparentemente mucha gente sí. Pero para mí, peor que un programador novato que trabaja en idiomas de escritura débil o dinámica, puedo escribir mejor código más rápido con Apps Hungarian que sin él.


4

Es increíblemente redundante e inútil son los IDE más modernos, donde hacen un buen trabajo para hacer que el tipo sea aparente.

Además, para mí, es molesto ver intI, strUserName, etc. :)


3
Como TraumaPony le dijo a Paul Batum, no todos ven el código en el IDE.
Chris Charabaruk

4

Si siento que se está impartiendo información útil, ¿por qué no debería ponerla allí donde está disponible?

Entonces, ¿a quién le importa lo que piensen los demás? Si lo encuentra útil, use la notación.


Porque solo hay uno de mí y un billón de otras personas que podrían mantener mi código más adelante. Como todas esas personas están en el equipo (pero aún no lo saben), me gustaría tener una idea si me votan.
Dustman

4

Soy mi experiencia, es malo porque:

1 - luego se rompe todo el código si necesita cambiar el tipo de una variable (es decir, si necesita extender un entero de 32 bits a un entero de 64 bits);

2: esta es información inútil ya que el tipo ya está en la declaración o usa un lenguaje dinámico donde el tipo real no debería ser tan importante en primer lugar.

Además, con un lenguaje que acepta programación genérica (es decir, funciones en las que el tipo de algunas variables no se determina cuando se escribe la función) o con un sistema de tipeo dinámico (es decir, cuando el tipo ni siquiera se determina en tiempo de compilación), ¿cómo nombraría su variables? Y la mayoría de los idiomas modernos admiten uno u otro, incluso en forma restringida.


4

En Joel Spolsky, Making Wrong Code Look Wrong , explica que lo que todos consideran la notación húngara (que él llama Systems Hungarian) no es lo que realmente pretendía ser (lo que él llama Apps Hungarian). Desplácese hacia abajo hasta el título Soy Hungría para ver esta discusión.

Básicamente, Systems Hungarian no tiene valor. Simplemente le dice lo mismo que su compilador y / o IDE le dirán.

Apps Hungarian te dice qué se supone que significa la variable, y en realidad puede ser útil.


4

Siempre he pensado que un prefijo o dos en el lugar correcto no dolería. Creo que si puedo impartir algo útil, como "Hola, esta es una interfaz, no cuente con un comportamiento específico", como en IEnumerable, debería hacerlo. Los comentarios pueden desordenar las cosas mucho más que un simple símbolo de uno o dos caracteres.


1
Nunca obtuve el ISomethingable. Si se puede habilitar, eso implica una interfaz de todos modos. (Al menos en Java)
tunaranch

4

Es una convención útil para nombrar controles en un formulario (btnOK, txtLastName, etc.), si la lista de controles aparece en una lista desplegable alfabética en su IDE.


4

Yo tiendo a usar la notación húngara con controles de servidor ASP.NET sólo , de lo contrario me resulta demasiado difícil de averiguar qué controles son lo que en el formulario.

Tome este fragmento de código:

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

Si alguien puede mostrar una mejor manera de tener ese conjunto de nombres de control sin húngaro, estaría tentado a pasar a él.


4

El artículo de Joel es genial, pero parece omitir un punto importante:

El húngaro hace que una 'idea' particular (tipo + nombre de identificador) sea única o casi única en toda la base de código, incluso una base de código muy grande.

Eso es enorme para el mantenimiento del código. Significa que puede usar una buena búsqueda de texto de una sola línea (grep, findtr, 'buscar en todos los archivos') para encontrar CADA mención de esa 'idea'.

¿Por qué es tan importante cuando tenemos IDE que saben leer el código? Porque todavía no son muy buenos en eso. Esto es difícil de ver en una pequeña base de código, pero es obvio en una grande, cuando la 'idea' podría mencionarse en comentarios, archivos XML, scripts de Perl y también en lugares fuera del control de la fuente (documentos, wikis, bases de datos de errores).

Debe tener un poco de cuidado incluso aquí, por ejemplo, pegar tokens en macros C / C ++ puede ocultar menciones del identificador. Tales casos pueden tratarse utilizando convenciones de codificación, y de todos modos tienden a afectar solo a una minoría de los identificadores en la base de código.

PD: Hasta el punto de usar el sistema de tipos frente al húngaro: es mejor usar ambos. Solo necesita un código incorrecto para que parezca incorrecto si el compilador no lo detectará por usted. Hay muchos casos en los que no es factible hacer que el compilador lo atrape. Pero donde sea factible, sí, ¡hazlo en su lugar!

Sin embargo, al considerar la viabilidad, tenga en cuenta los efectos negativos de dividir los tipos. por ejemplo, en C #, envolver 'int' con un tipo no incorporado tiene enormes consecuencias. Por lo tanto, tiene sentido en algunas situaciones, pero no en todas.


4

Desacreditando los beneficios de la notación húngara

  • Proporciona una forma de distinguir variables.

Si el tipo es todo lo que distingue un valor de otro, entonces solo puede ser para la conversión de un tipo a otro. Si tiene el mismo valor que se está convirtiendo entre tipos, es probable que deba hacerlo en una función dedicada a la conversión. (He visto restos sobrantes de VB6 que usan cadenas en todos sus parámetros de método simplemente porque no pudieron descubrir cómo deserializar un objeto JSON, o comprender adecuadamente cómo declarar o usar tipos anulables ) . Si tiene dos variables distinguidas solo por el El prefijo húngaro, y no son una conversión de uno a otro, entonces debe elaborar su intención con ellos.

  • Hace que el código sea más legible.

He descubierto que la notación húngara hace que las personas sean perezosas con sus nombres variables. Tienen algo para distinguirlo y no sienten la necesidad de elaborar su propósito. Esto es lo que normalmente encontrará en el código anotado húngaro vs. moderno: sSQL vs. groupSelectSql ( o generalmente no sSQL en absoluto porque se supone que están usando el ORM que fue implementado por desarrolladores anteriores ), sValue vs. formCollectionValue ( o, por lo general, tampoco sValue, porque están en MVC y deberían usar sus características de enlace de modelo ), sType vs. PublishSource, etc.

No puede ser legibilidad. Veo más sTemp1, sTemp2 ... sTempN de cualquier sobrante de VB6 húngaro dado que todos los demás combinados.

  • Previene errores.

Esto sería en virtud del número 2, que es falso.


3

En palabras del maestro:

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

Una lectura interesante, como siempre.

Extractos:

"Alguien, en algún lugar, leyó el artículo de Simonyi, donde usó la palabra" tipo ", y pensó que se refería a tipo, como clase, como en un sistema de tipos, como el tipo de verificación que hace el compilador. No lo hizo. Explicó muy cuidadosamente exactamente lo que quería decir con la palabra "tipo", pero no ayudó. El daño ya estaba hecho ".

"Pero todavía hay una enorme cantidad de valor para Apps Hungarian, ya que aumenta la colocación en el código, lo que hace que el código sea más fácil de leer, escribir, depurar y mantener, y, lo más importante, hace que el código incorrecto se vea mal".

Asegúrese de tener algo de tiempo antes de leer Joel On Software. :)


No hay tiempo ahora que tengo Stackoverflow. Creo que la mera asociación de Spolsky con el proyecto debe estar haciéndolo. :)
Dustman

3

Muchas rasones:

  • Cualquier IDE moderno le dará el tipo de variable simplemente pasando el mouse sobre la variable.
  • La mayoría de los nombres de tipo son largos (piense en HttpClientRequestProvider ) para usarse razonablemente como prefijo.
  • La información de tipo no lleva la información correcta , solo parafrasea la declaración de la variable, en lugar de describir el propósito de la variable (piense en myInteger vs. pageSize ).

2

No creo que todos estén rabiosamente en contra. En idiomas sin tipos estáticos, es bastante útil. Definitivamente lo prefiero cuando se usa para dar información que aún no está en el tipo. Al igual que en C, char * szName dice que la variable se referirá a una cadena terminada en nulo, que no está implícita en char *, por supuesto, un typedef también ayudaría.

Joel tenía un gran artículo sobre el uso del húngaro para saber si una variable estaba codificada en HTML o no:

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

De todos modos, no me gusta el húngaro cuando se usa para transmitir información que ya conozco.


Creo que la primera oración podría creer las respuestas en esta página.
Dustman

@Dustman Bueno, no te ya se sabe que las cadenas C tienen una terminación nula? Veo cómo sería útil cuando la cadena podría no serlo, pero eso es raro, por lo que creo que el uso de la convención debería limitarse a esos casos.
Plumenator

No todos los caracteres * son una cadena c terminada en nulo. El objetivo del húngaro es usarlo para todas las variables, incluso las que entran en el caso común. En definitiva, me siento como tú, y por lo tanto no lo uso en C.
Lou Franco


2

Comencé a codificar más o menos cuando se inventó la notación húngara y la primera vez que me vi obligado a usarlo en un proyecto lo odié.

Después de un tiempo, me di cuenta de que cuando se hacía correctamente, realmente ayudaba y en estos días me encanta.

Pero como todo lo bueno, tiene que ser aprendido y entendido, y hacerlo correctamente lleva tiempo.


1

La notación húngara fue abusada, particularmente por Microsoft, lo que llevó a prefijos más largos que el nombre de la variable, y muestra que es bastante rígida, particularmente cuando cambia los tipos (el infame lparam / wparam, de diferente tipo / tamaño en Win16, idéntico en Win32 )

Por lo tanto, tanto debido a este abuso, como a su uso por parte de M $, se consideró inútil.

En mi trabajo, codificamos en Java, pero el fundador proviene del mundo MFC, así que use un estilo de código similar (llaves alineadas, ¡me gusta! ), s_ a miembros estáticos, etc.).

Y dijeron que todas las variables deberían tener un prefijo que muestre su tipo (por ejemplo, un BufferedReader se llama brData). Lo que se muestra como una mala idea, ya que los tipos pueden cambiar pero los nombres no siguen, o los codificadores no son consistentes en el uso de estos prefijos (¡incluso veo a Buffer, theProxy, etc.!).

Personalmente, elegí algunos prefijos que considero útiles, el más importante es b para prefijar las variables booleanas, ya que son las únicas en las que permito la sintaxis como if (bVar)(sin el uso de la transmisión automática de algunos valores a verdadero o falso). Cuando codifiqué en C, utilicé un prefijo para las variables asignadas con malloc, como recordatorio de que debería liberarse más tarde. Etc.

Entonces, básicamente, no rechazo esta notación en su conjunto, sino que tomé lo que parece adecuado para mis necesidades.
Y, por supuesto, cuando contribuyo a algún proyecto (trabajo, código abierto), ¡solo uso las convenciones vigentes!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.