Was ist der Vorteil, wenn Sie keine ungarische Notation verwenden?

101

Eines der Dinge, mit denen ich zu kämpfen habe, ist, die ungarische Notation nicht zu verwenden. Ich möchte nicht zur Variablendefinition gehen müssen, nur um zu sehen, welcher Typ es ist. Wenn ein Projekt umfangreich wird, ist es schön, eine Variable mit dem Präfix 'bool' zu betrachten und zu wissen, dass nach true / false anstelle eines 0 / 1- Werts gesucht wird.

Ich arbeite auch viel in SQL Server. Ich stelle meinen gespeicherten Prozeduren 'sp' und meinen Tabellen 'tbl' voran, ganz zu schweigen von all meinen Variablen in der Datenbank.

Ich sehe überall, dass niemand wirklich die ungarische Notation verwenden möchte, bis zu dem Punkt, an dem sie es vermeiden. Meine Frage ist, was der Vorteil ist, wenn man keine ungarische Schreibweise verwendet, und warum meidet die Mehrheit der Entwickler dies wie die Pest?

user29981
quelle
39
Welche Sprache / IDE verwenden Sie? In Visual Studio müssen Sie nicht zur Definition gehen, um den Typ einer Variablen zu kennen, da die IDE ihn Ihnen zur Verfügung stellt. In Sprachen, in denen Typen nicht erzwungen werden, wie z. B. PHP, müssen Sie den Typ die meiste Zeit nicht kennen (da Sie einem Booleschen Wert 0 oder 1 zuweisen können).
Arseni Mourzenko
10
@MainMa Ich bin mir nicht sicher, ob das ein guter Grund ist, den Typ eines Wertes in PHP nicht zu kennen.
Rei Miyasaka
29
"Wann Projekte umfangreich werden" ... sollte keine Rolle spielen. Es sollte zu jedem Zeitpunkt nur eine kleine Anzahl von Variablen im Gültigkeitsbereich geben: eine Handvoll Klassenvariablen und eine andere Handvoll Methodenargumente. Wenn Sie sie nicht gerade halten können, ist die Klasse zu groß oder die Methode zu lang. Die ungarische Notation wurde für die Windows C-Programmierung erfunden, im Grunde genommen als Umgehungslösung für die schreckliche Windows-API. Nichts Ähnliches wurde jemals für die Unix-Entwicklung vorgeschlagen oder gewünscht.
Kevin Cline
20
Was ist der Vorteil , wenn Sie die ungarische Schreibweise "Nicht von Ihren Mitarbeitern gehasst werden" nicht verwenden?
Sean Patrick Floyd
25
adjUngarian nNotation vIs adjHard prepTo vRead.
Dan04

Antworten:

148

Weil seine ursprüngliche Absicht (siehe http://www.joelonsoftware.com/articles/Wrong.html und http://fplanque.net/Blog/devblog/2005/05/11/hungarian_notation_on_steroids ) missverstanden wurde und es wurde ( ab) dient dazu, sich zu erinnern, welcher Typ eine Variable ist, wenn die von ihnen verwendete Sprache nicht statisch typisiert ist. In jeder statisch getippten Sprache benötigen Sie keine zusätzlichen Präfixe, um den Typ einer Variablen zu bestimmen. In vielen untypisierten Skriptsprachen kann es helfen, aber es wurde oft so missbraucht, dass es völlig unhandlich wurde. Leider haben die Leute es gerade zu einem der "bösen" Dinge gemacht, die Sie vermeiden sollten, anstatt zu der ursprünglichen Absicht der ungarischen Notation zurückzukehren.

Kurz gesagt, die ungarische Notation sollte Variablen eine gewisse Semantik voranstellen. Wenn Sie beispielsweise Bildschirmkoordinaten haben (links, oben, rechts, unten), werden Variablen mit absoluten Bildschirmpositionen mit " abs" und Variablen mit Positionen relativ zu einem Fenster mit " rel" vorangestellt . Auf diese Weise ist es für jeden Leser offensichtlich, wenn Sie eine relative Koordinate an eine Methode übergeben, die absolute Positionen erfordert.

update (als antwort auf kommentar von delnan)

IMHO sollte die missbrauchte Version wie die Pest vermieden werden, weil:

  • es erschwert die Benennung. Wenn (ab) die ungarische Notation verwendet wird, wird immer darüber diskutiert, wie genau die Präfixe sein müssen. Zum Beispiel: listboxXYZoder MyParticularFlavourListBoxXYZ.
  • Dadurch werden Variablennamen länger, ohne dass das Verständnis für die Funktion der Variablen erleichtert wird.
  • Es besiegt den Gegenstand der Übung, wenn, um lange Präfixe zu vermeiden, diese auf Abkürzungen gekürzt werden und Sie ein Wörterbuch benötigen, um zu wissen, was jede Abkürzung bedeutet. Ist eine uiganze Zahl ohne Vorzeichen? eine nicht referenzierte gezählte Schnittstelle? etwas mit Benutzeroberflächen zu tun? Und diese Dinge können lang werden . Ich habe Präfixe von mehr als 15 scheinbar zufälligen Zeichen gesehen, die den genauen Typ der Var wiedergeben sollen, aber wirklich nur mystifizieren.
  • es wird schnell veraltet. Wenn Sie den Typ einer Variablen ändern, vergessen people invariably (lol), das Präfix zu aktualisieren, um die Änderung widerzuspiegeln, oder aktualisieren Sie es absichtlich nicht, da dies Codeänderungen überall auslösen würde, wo die Variable verwendet wird ...
  • Es erschwert das Sprechen über Code, weil als "@g". sagte: Variablennamen mit ungarischer Schreibweise sind in der Regel schwer auszusprechende Buchstabensuppe. Dies verhindert die Lesbarkeit und das Erörtern von Code, da Sie keinen der Namen "sagen" können.
  • ... viel mehr, an das ich mich im Moment nicht erinnern kann. Vielleicht, weil ich das Vergnügen hatte, mich lange nicht mehr mit der missbrauchten ungarischen Notation auseinandersetzen zu müssen ...
Marjan Venema
quelle
9
@ Surfer513: Eigentlich bevorzuge ich Suffixe beim Benennen von Steuerelementen. Für mich ist es weitaus interessanter, alle Steuerelemente zu finden, die sich auf ein bestimmtes Thema / einen bestimmten Aspekt beziehen, als alle Bearbeitungssteuerelemente ... Wenn ich das Steuerelement suchen möchte, in das der Benutzer einen Clientnamen eingeben kann, beginne ich mit der Suche client statt txt, da es sich möglicherweise nicht um einen txt (edit), sondern um ein Memo oder einen Richedit oder ... handelt. Könnte sogar ein Kombinationsfeld sein, um es in zuvor eingegebenen Client-Namen zu finden ...
Marjan Venema
8
@ Surfer513: Und heutzutage neige ich dazu, Suffixe nur zu verwenden, wenn ich zwischen zwei Steuerelementen unterscheide, die sich mit der gleichen Sache befassen. Zum Beispiel die Bezeichnung und die Bearbeitung des Kundennamens. Und nicht selten beziehen sich die Suffixe nicht auf die Art des Steuerelements, sondern auf dessen Zweck: beispielsweise ClientCaption und ClientInput.
Marjan Venema
3
Beachten Sie auch, dass Sie mit Intellisense in VS 2010 den gesamten Namen und nicht nur den Anfang durchsuchen können . Wenn Sie Ihrem Steuerelement den Namen "firstNameTextBox" geben und "textb" eingeben, wird es Ihr Steuerelement finden und auflisten.
Adam Robinson
4
"... die missbrauchte Version wird vermieden wie die Plakette ...", das heißt, etwas weniger vermieden als Zahnstein und Zahnfleischentzündung? ;-)
Ben Mosher
4
@ Marjan: Natürlich hätte ein Compiler das aufgreifen können. Wenn jede Einheit durch einen Typ dargestellt wird, können Sie nicht versehentlich einen für einen anderen übergeben. Wenn Sie hier ein AbsoluteXTypeund ein haben RelativeYType, können Sie nicht irrtümlicherweise eine relative Y-Koordinate für eine absolute X-Koordinate übergeben. Ich bevorzuge Variablen, die inkompatible Entitäten darstellen, von inkompatiblem Typ, anstatt inkompatible Präfixe zu haben. Der Compiler achtet nicht auf Präfixe (oder Suffixe).
Matthieu M.
74

Die ungarische Notation ist in modernen Programmierumgebungen und in der Form der Tautologie ein Anti-Muster .

Es werden unnötigerweise Informationen ohne Nutzen und zusätzlichen Wartungsaufwand wiederholt. Was passiert, wenn Sie Ihren intTyp auf einen anderen Typ ändern long, müssen Sie jetzt Ihre gesamte Codebasis suchen und ersetzen, um alle Variablen umzubenennen, oder sie sind jetzt semantisch falsch, was schlimmer ist, als wenn Sie den Typ nicht im Namen dupliziert hätten.

Es verstößt gegen das DRY-Prinzip. Wenn Sie Ihren Datenbanktabellen eine Abkürzung voranstellen müssen, um Sie daran zu erinnern, dass es sich um eine Tabelle handelt, sind Sie definitiv nicht in der Lage, Ihre Tabellen semantisch aussagekräftig genug zu benennen. Gleiches gilt für alle anderen Dinge, mit denen Sie dies tun. Es ist nur eine zusätzliche Eingabe, die in einer modernen Entwicklungsumgebung keinen Nutzen bringt.

user7519
quelle
2
"Was passiert, wenn Sie inteinen anderen Typ als long... wählen?" Einfach: <sarcasm> Ändern Sie den Namen nicht, da nicht absehbar ist, an wie vielen Stellen sich die Änderung auswirkt. </ Sarcasm> Nun haben Sie also eine Variable, deren Name geändert wird Ungarischer Name widerspricht seiner Umsetzung. Es ist absolut nicht abzusehen, wie weit verbreitet die Änderung des Namens ist, wenn die Variable / Funktion öffentlich sichtbar ist.
David Hammen
2
Der verlinkte Artikel ist fantastisch und eine Lektüre wert. +1
Marty Pitt
6
@David, schauen Sie sich nur die Win32-API an, die mit Variablen, Parametern und sogar Methodennamen durchsetzt ist, die in ungarischer Notation (was bei MS erforderlich ist) einen 8-Bit- oder 16-Bit-Wert anzeigen, obwohl sie alle 32-Bit-Werte haben Werte seit der Einführung von Windows 95 im Jahr 1994 (also vor fast 17 Jahren).
Jwenting
2
@Secure: Ich würde sagen, das sollten automatisierte Tests tun. Nicht Programmierer.
Joel
2
@Secure möglicherweise nicht in einer internen Anwendung, aber wenn Sie eine öffentliche API wie die Windows-API verwalten, ist dies ein großes Problem.
23.
51

Wikipedia hat eine Liste von Vor- und Nachteilen der ungarischen Notation und kann daher wahrscheinlich die umfassendste Antwort auf diese Frage geben. Die bemerkenswerten Meinungen sind auch eine ziemlich interessante Lektüre.

Der Vorteil, keine ungarische Notation zu verwenden, besteht im Wesentlichen darin, dass nur die Nachteile vermieden werden:

  • Die ungarische Notation ist überflüssig, wenn der Compiler die Typprüfung vornimmt. Compiler für Sprachen, die die Typprüfung bereitstellen, stellen sicher, dass die Verwendung einer Variablen automatisch ihrem Typ entspricht. Kontrollen mit dem Auge sind überflüssig und unterliegen menschlichen Fehlern.

  • In allen modernen integrierten Entwicklungsumgebungen werden variable Typen bei Bedarf angezeigt und Vorgänge, die inkompatible Typen verwenden, werden automatisch gekennzeichnet, sodass die Notation weitgehend veraltet ist.

  • Die ungarische Notation wird verwirrend, wenn sie zur Darstellung mehrerer Eigenschaften verwendet wird, z. B . a_crszkvc30LastNameCol: ein konstantes Referenzargument, das den Inhalt einer Datenbankspalte LastNamedes Typs enthält, varchar(30)der Teil des Primärschlüssels der Tabelle ist.

  • Dies kann zu Inkonsistenzen führen, wenn Code geändert oder portiert wird. Wenn der Variablentyp geändert wird, stimmt entweder die Dekoration des Variablennamens nicht mit dem neuen Typ überein, oder der Variablenname muss geändert werden. Ein besonders bekanntes Beispiel ist der Standardtyp WPARAMund der zugehörige wParamformale Parameter in vielen Windows-Systemfunktionsdeklarationen. Das 'w' steht für 'word', wobei 'word' die native Wortgröße der Hardware-Architektur der Plattform ist. Es war ursprünglich ein 16-Bit-Typ auf 16-Bit-Wortarchitekturen, wurde jedoch in späteren Versionen des Betriebssystems unter Beibehaltung seines Typs in einen 32-Bit-Typ auf 32-Bit-Wortarchitekturen oder 64-Bit-Typ auf 64-Bit-Wortarchitekturen geändert ursprünglicher Name (sein wahrer zugrunde liegender Typ istUINT_PTR(dh eine ganze Zahl ohne Vorzeichen, die groß genug ist, um einen Zeiger aufzunehmen). Die semantische Impedanz und damit die Verwirrung und Inkonsistenz der Programmierer von Plattform zu Plattform gehen davon aus, dass 'w' in diesen verschiedenen Umgebungen für 16-Bit steht.

  • Wenn Sie die Verwendung einer Variablen kennen, müssen Sie meistens deren Typ kennen. Wenn die Verwendung einer Variablen nicht bekannt ist, kann sie nicht von ihrem Typ abgeleitet werden.

  • Die ungarische Notation reduziert die Vorteile der Verwendung funktionsreicher Code-Editoren, die die Vervollständigung von Variablennamen unterstützen, erheblich, da der Programmierer zuerst den gesamten Typ-Bezeichner eingeben muss.

  • Dadurch wird der Code weniger lesbar, da der Zweck der Variablen durch unnötige Typ- und Gültigkeitsbereichspräfixe verschleiert wird.

  • Die zusätzlichen Typinformationen können aussagekräftigere Namen nur unzureichend ersetzen. ZB sDatabasesagt dem Leser nicht, was es ist. databaseNamekönnte ein aussagekräftigerer Name sein.

  • Wenn Namen ausreichend beschreibend sind, können die zusätzlichen Typinformationen redundant sein. ZB firstNameist höchstwahrscheinlich eine Zeichenfolge. Das Benennen sFirstNamefügt dem Code nur Unordnung hinzu.

Ich selbst benutze diese Notation nicht, weil ich das unnötige technische Rauschen nicht mag. Ich weiß fast immer, mit welchem ​​Typ ich es zu tun habe und ich möchte eine saubere Sprache in meinem Domain-Modell, aber ich schreibe hauptsächlich in statischen und stark typisierten Sprachen.

Falcon
quelle
1
Dies sollte die richtige Antwort sein. Es ist so schön. +1
Saeed Neamati
Du bist zu nett, Saeed. Ich schätze Ihre Anerkennung, aber die anderen Antworten auf diese Frage sind auch wirklich gut.
Falcon
11
Hochgestuft für einen einzelnen Satz: " Wenn man die Verwendung einer Variablen kennt, muss man meistens ihren Typ kennen. Wenn die Verwendung einer Variablen nicht bekannt ist, kann man sie auch nicht von ihrem Typ ableiten. " - IMHO, Dies ist der Hauptgrund, die ungarische Notation zu vermeiden.
Daniel Pryden
19

Als MS SQL Server spezifisches Problem:

Alle gespeicherten Prozeduren mit dem Präfix 'sp_' werden zuerst in der Master-Datenbank gesucht und nicht in der, in der sie erstellt wurden. Dadurch wird die Ausführung der gespeicherten Prozedur verzögert.

Tsundoku
quelle
4
+1 für einige sehr coole Informationen. Ich benutze 'sp' als gespeichertes Proc-Präfix, nicht 'sp_'. Aber das ist definitiv eine sehr sehr interessante Tatsache und ein konkreter Grund, 'sp_' nicht als gespeichertes Proc-Präfix zu verwenden.
2
+1 Ich habe das nie gewusst, und als ich anfing, an SQL Server zu arbeiten, wurden alle SPs an meinem Arbeitsplatz mit Präfix versehen, sp_sodass ich mich nur an die Konvention hielt.
Michael
Toller Punkt, aber nichts mit dieser Frage zu tun (mit sq und nicht mit _sp). Es ist so, als würde man den Schemanamen für Objekte weglassen, die nicht im Standardschema enthalten sind.
JeffO
1
Für vom Benutzer gespeicherte Prozeduren habe ich herkömmlicherweise "usp_" verwendet. Dies diente dazu, das erwähnte Problem zu vermeiden UND für den Leser zu unterscheiden, ob der Sproc ein System oder ein Benutzer war.
Umbrella
15

IMO ist der größte Vorteil, wenn Sie kein Ungarisch verwenden, die Tatsache, dass Sie dazu gezwungen werden, aussagekräftige Namen zu verwenden . Wenn Sie Variablen richtig benennen, sollten Sie sofort wissen, um welchen Typ es sich handelt, oder in der Lage sein, ihn in einem gut konzipierten System relativ schnell abzuleiten. Wenn Sie sich verlassen müssen stroder blnoder schlechter alle objPräfixe zu wissen , welche Art eine Variable ist, würde ich argumentieren , es eine Name Problem gibt - entweder schlechte Variablennamen im Allgemeinen oder viel zu allgemeine Bedeutung zu vermitteln.

Aus persönlicher Erfahrung ist das Hauptszenario, in dem ich Ungarisch gesehen habe, entweder "Frachtkult" -Programmierung (dh, es wird von anderem Code verwendet, verwenden wir es also weiterhin, nur weil) oder in VB.NET, um die Tatsache zu umgehen, dass es sich um eine Sprache handelt Groß- / Kleinschreibung wird Person oPerson = new Personnicht berücksichtigt (z. B. weil Sie nicht verwenden können Person person = new Personund Person p = new Personzu vage sind); Ich habe in diesem speziellen Fall auch das Präfix "the" oder "my" (wie in Person thePerson = new Personoder hässlicher Person myPerson = new Person) gesehen.

Ich werde das Hinzufügen nur Zeit verwende ich Ungar für ASP.NET - Steuerelemente zu sein scheint und das ist wirklich eine Frage der Wahl. Ich finde es sehr hässlich zu tippen TextBoxCustomerNameoder CustomerNameTextBoxgegenüber dem Einfacheren txtCustomerName, aber selbst das fühlt sich "dreckig" an. Ich bin der Meinung, dass für Steuerelemente eine Art Namenskonvention verwendet werden sollte, da es mehrere Steuerelemente geben kann, die dieselben Daten anzeigen.

Wayne M
quelle
13

Ich werde mich nur auf SQL Server konzentrieren, da Sie es erwähnt haben. Ich sehe keinen Grund, 'tbl' vor einen Tisch zu stellen. Sie können sich jeden tSQL-Code ansehen und eine Tabelle danach unterscheiden, wie sie verwendet wird. Sie würden nie Select from stored_procedure.oder Select from table(with_param)möchten, dass Sie eine UDF oder Execute tblTableOrViewNameeine gespeicherte Prozedur möchten .

Tabellen könnten mit einer Ansicht verwechselt werden, aber wenn es darum geht, wie sie verwendet werden; Es gibt keinen Unterschied. Worum geht es also? Die ungarische Notation erspart Ihnen möglicherweise die Zeit, die Sie für die Suche in SSMS (unter Tabelle oder Ansichten?) Benötigen, aber das war es auch schon.

Variablen können ein Problem darstellen, aber sie müssen deklariert werden. Wie weit von Ihrer Deklarierungsanweisung entfernt möchten Sie eine Variable verwenden? Ein paar Zeilen zu scrollen sollte keine große Sache sein, es sei denn, Sie schreiben sehr lange Prozeduren. Es kann eine gute Idee sein, den langen Code ein wenig aufzubrechen.

Was Sie beschreiben, ist ein Schmerz, aber die ungarische Notationslösung löst das Problem nicht wirklich. Sie können sich den Code einer anderen Person ansehen und feststellen, dass der Variablentyp möglicherweise geändert wird, was jetzt eine Änderung des Variablennamens erforderlich macht. Nur noch eine Sache zu vergessen. Und wenn ich ein VarChar verwende, müssen Sie sich die declare-Anweisung trotzdem ansehen, um die Größe zu ermitteln. Beschreibende Namen werden Sie wahrscheinlich weiterbringen. @PayPeriodStartDate erklärt sich so ziemlich von selbst.

JeffO
quelle
2
@Surfer: Ein Primärschlüssel ist anders, weil "PK" nicht der Typ ist. "PK_TableName" besagt "Dies ist der Primärschlüssel für TableName", nicht "Dies ist ein TableName vom Typ PK". Übrigens ... es hört sich nicht so an, als würdest du den Argumenten hier wirklich zuhören. Bitte hören Sie auf, diese verabscheuungswürdige Praxis anzuwenden, die bis heute die kollektive Qualität des gesamten Codes beeinträchtigt.
Aaronaught
2
@Aaronaught, Sie spezifizieren einen Aspekt der ungarischen Notation ( en.wikipedia.org/wiki/Hungarian_notation ). Es ist nicht nur Typ, sondern auch Verwendungszweck. Das Präfix 'pk' für einen Primärschlüssel ist also die ungarische Notation. Ich höre mir hier Argumente an, aber es gibt Ausnahmen (wie die Primärschlüsselsituation), in denen HN vorteilhaft zu sein scheint. Vielleicht, vielleicht nicht. Ich versuche immer noch, meinen Kopf für alle Szenarien um die Do's und Dont's zu wickeln. Ich habe heute einiges darüber gelernt und einige großartige Gedanken ausgelöst.
3
@Surfer: Das stimmt einfach nicht. Die ungarische Schreibweise beschreibt entweder den Typ (schlechte Version) oder eine bestimmte Verwendung des Typs (weniger schlechte Version). PK ist weder, es beschreibt nicht einfach etwas über den Typ, es beschreibt ein Verhalten . Wenn ich beispielsweise von einem Alter spreche, ist es durchaus uninteressant, dass es sich um eine Ganzzahl handelt. Wenn es sich jedoch um eine Datenbankeinschränkung handelt, ist der "Primärschlüssel für Tabelle X" genau das, was wichtig ist.
Aaronaught
4
Ich mag deinen vorletzten Absatz. Die Begründung meiner Firma für die Verwendung der ungarischen Notation lautet: "So können wir schnell erkennen, welche Variablen global sind und welche nicht." Und dann sehen Sie sich die Variablendeklarationen an und es gibt 300 Variablen pro Datei, einige m * für modular (global), einige v * für lokal, AUCH WENN SIE AUF MODULARER EBENE DEKLARIERT SIND. "Oh, das liegt daran, dass sie nur als Einheimische gedacht sind, nicht als modular." facepalm
corsiKa
3
@Aaronaught: In meinem aktuellen Projekt verwenden wir Tabellennamen mit dem Präfix tbl_ . Obwohl ich kein großer Fan dieser Praxis bin, verstehe ich nicht, wie dies "die kollektive Qualität des gesamten Codes herabsetzt" . Können Sie vielleicht ein Beispiel geben?
Treb
6

Eine andere Sache ist, welche Abkürzungen würden Sie für ein gesamtes Framework wie .NET verwenden? Ja, es ist so einfach, sich daran zu erinnern, dass es sich btnum eine Schaltfläche und txtein Textfeld handelt. Aber was denkst du über so etwas StringBuilder? strbld? Was ist CompositeWebControl? Verwenden Sie so etwas:

CompositeWebControl comWCMyControl = new CompositeWebControl();

Eine der Ineffizienzen der ungarischen Notation bestand darin, dass durch immer größere Frameworks nicht nur ein zusätzlicher Nutzen, sondern auch eine höhere Komplexität für die Entwickler erzielt wurde, da sie nun mehr und mehr die nicht standardmäßigen Präfixe lernen mussten.

Saeed Neamati
quelle
6

Aus meiner Sicht ist die ungarische Notation ein Trick, um ein ungenügend leistungsfähiges Typensystem zu umgehen. In Sprachen, in denen Sie Ihre eigenen Typen definieren können, ist es relativ einfach, einen neuen Typ zu erstellen, der das von Ihnen erwartete Verhalten codiert. In Joel Spolskys Schimpfen über die ungarische Notation gibt er ein Beispiel für die Erkennung möglicher XSS-Angriffe, indem er angibt, dass eine Variable oder Funktion entweder unsicher (wir) oder sicher (s) ist, die visuelle Prüfung jedoch weiterhin vom Programmierer abhängig ist. Wenn Sie stattdessen über ein erweiterbares Typsystem verfügen, können Sie einfach zwei neue Typen erstellen, UnsafeString und SafeString, und diese dann entsprechend verwenden. Als Bonus wird die Art der Kodierung:

SafeString encode(UnsafeString)

Wenn Sie nicht auf die Interna von UnsafeString zugreifen oder andere Konvertierungsfunktionen verwenden, ist dies die einzige Möglichkeit, von einem UnsafeString zu einem SafeString zu gelangen. Wenn alle Ihre Ausgabefunktionen nur Instanzen von SafeString verwenden, ist es unmöglich, eine nicht maskierte Zeichenfolge auszugeben [Bloßstellen bei Konvertierungen wie StringToSafeString (someUnsafeString.ToString ())].

Es sollte offensichtlich sein, warum es dem Versuch überlegen ist, den Code von Hand oder in diesem Fall per Auge überprüfen zu lassen, dass das Typensystem die Integrität Ihres Codes überprüft.

In einer Sprache wie C sind Sie natürlich der Meinung, dass ein Int ein Int ein Int ist, und Sie können nicht viel dagegen tun. Man könnte immer mit Strukturen spielen, aber es ist fraglich, ob das eine Verbesserung ist oder nicht.

Was die andere Interpretation der ungarischen Notation anbelangt, so ist der IE, dem der Variablentyp vorangestellt wird, schlichtweg dumm und ermutigt zu faulen Praktiken wie dem Benennen von Variablen uivxwFoo anstelle von etwas Sinnvollem wie countOfPeople.

Orclev
quelle
Wie würde man einen .NET- oder Java-Typ deklarieren, um zu beschreiben, " int[]welcher frei modifiziert, aber niemals geteilt werden int[]darf " oder " welcher frei geteilt werden darf nur unter Dingen, die ihn niemals ändern werden"? Wenn ein int[]Feld foodie Werte einkapselt, {1,2,3}kann man es einkapseln lassen, {2,2,3}ohne zu wissen, welchen "Typ" int[]es darstellt? Ich denke, Java und .NET wären viel besser gewesen, wenn sie - ohne die Unterstützung von Typsystemen - zumindest eine Namenskonvention zur Unterscheidung dieser Typen eingeführt hätten.
Supercat
4

Die ungarische Notation ist in einer statisch typisierten Sprache fast völlig unbrauchbar. Es ist eine grundlegende IDE-Funktion, um den Typ einer Variablen anzuzeigen, indem Sie mit der Maus darüber fahren oder auf andere Weise. Außerdem können Sie sehen, was der Typ ist, indem Sie ein paar Zeilen an der Stelle nachsehen, an der er deklariert wurde, wenn keine Typinferenz vorliegt. Der springende Punkt bei der Typinferenz ist, dass das Rauschen des Typs nicht überall wiederholt wird. Daher wird die ungarische Notation in Sprachen mit Typinferenz normalerweise als eine schlechte Sache angesehen.

In dynamisch getippten Sprachen kann es manchmal helfen, aber für mich fühlt es sich unidiomatisch an. Sie haben bereits aufgegeben, Ihre Funktionen auf exakte Domains / Codomains zu beschränken. Wenn alle Ihre Variablen in ungarischer Schreibweise benannt sind, geben Sie nur wieder, was Ihnen ein Typensystem gegeben hätte. Wie drückt man eine polymorphe Variable aus, die eine Ganzzahl oder eine Zeichenfolge in ungarischer Notation sein kann? "IntStringX"? "IntOrStringX"? Der einzige Ort, an dem ich jemals die ungarische Notation verwendet habe, war der Assembler-Code, weil ich versucht habe, das zurückzuholen, was ich mit einem Typensystem bekommen hätte, und es war das erste, was ich jemals codiert habe.

Egal, es ist mir egal, wie die Leute ihre Variablen nennen, der Code wird wahrscheinlich immer noch genauso unverständlich sein. Entwickler verschwenden viel zu viel Zeit mit Stil- und Variablennamen, und am Ende des Tages erhalten Sie immer noch eine Menge Bibliotheken mit völlig anderen Konventionen in Ihrer Sprache. Ich entwickle eine symbolische (dh nicht textbasierte) Sprache, in der es keine Variablennamen, nur eindeutige Bezeichner und vorgeschlagene Namen für Variablen gibt (aber die meisten Variablen haben noch keinen vorgeschlagenen Namen, da es für einfach keinen vernünftigen Namen gibt Sie); Wenn Sie nicht vertrauenswürdigen Code überwachen, können Sie sich nicht auf Variablennamen verlassen.

Longpoke
quelle
Es ist auch ziemlich nutzlos für die meisten dynamisch getippten Sprachen!
James Anderson
2
Für IDEs ist dies sogar noch schlimmer als für manuelles Codieren, da die Codevervollständigung drastisch verlangsamt wird. Wenn Sie 100 Ganzzahlvariablen haben, können Sie durch Eingabe von int <alt-space> (zum Beispiel) 100 Elemente zum Blättern aufrufen. Wenn Sie intVeryLongVariableName benötigen, ist die Code-Vervollständigung problematisch. Ohne Ungarisch würden Sie nur sehr <alt-space> eingeben und haben nur 1 oder 2 Optionen.
Jwenting
3

Wie in einem solchen Fall üblich, werde ich eine Antwort posten, bevor ich die Antworten anderer Teilnehmer lese. 

Ich sehe drei "Bugs" in Ihrer Vision: 

1) Wenn Sie den Typ einer Variablen / eines Parameters / eines Attributs / einer Spalte kennen möchten, können Sie mit der Maus darüber fahren oder darauf klicken, und es wird in der modernsten IDE angezeigt. Ich weiß nicht, welche Tools Sie verwenden, aber das letzte Mal, als ich gezwungen war, in einer Umgebung zu arbeiten, die diese Funktion nicht bot, war im 20. Jahrhundert COBOL, nein, Fortran und mein Chef Ich habe nicht verstanden, warum ich gegangen bin. 

2 / Die Typen können sich während des Entwicklungszyklus ändern. Eine 32-Bit-Ganzzahl kann zu einem bestimmten Zeitpunkt eine 64-Bit-Ganzzahl werden, aus guten Gründen, die zu Beginn des Projekts nicht erkannt wurden. Das Umbenennen von intX in longX oder das Belassen eines Namens, der auf den falschen Typ verweist, ist schlechtes Karma. 

3) Was Sie verlangen, ist tatsächlich eine Redundanz. Redundanz ist kein besonders gutes Entwurfsmuster oder keine Gewohnheit. Sogar Menschen zögern zu viel Redundanz. Sogar Menschen zögern zu viel Redundanz. 

Oqaqiq
quelle
Ich verstehe die fortgeschrittene / moderne IDE und stimme Ihnen vollkommen zu. Aber was ist mit dem Datenbankdesign? Angenommen, Sie haben eine Spalte oder einen Parameter für eine gespeicherte Prozedur. Der Schwebetrick funktioniert mit so etwas nicht wirklich. Sie müssten sich die Tabelle / gespeicherte Prozessdefinition ansehen. Was machst du dafür?
3

Ich glaube, dass es ein Symptom ist, dringend Ungarn zu brauchen .
Ein Symptom für zu viele globale Variablen ... oder dafür, dass Funktionen zu lang sind, um erreichbar zu sein .

Wenn Ihre Variablendefinition nicht in Sicht ist, haben Sie normalerweise Probleme.
Und wenn Ihre Funktionen keinen denkwürdigen Konventionen folgen , gibt es wieder große Probleme.

Das ist ... so ziemlich der Grund, warum es an vielen Arbeitsplätzen ausgeblendet wird, nehme ich an.

Es entstand aus Sprachen , die es brauchten .
Zu Zeiten globaler Variablen bonanza . (aus Mangel an Alternativen)
Es hat uns gut gedient.

Die einzige wirkliche Verwendung wir es heute haben , ist der Joel Spolsky ein .
Verfolgung bestimmter Attribute der Variablen, z. B. ihrer Sicherheit .

( zB "Hat die Variable safeFoobargrünes Licht, um in eine SQL-Abfrage eingespeist zu werden?
- Wie es heißt safe, ja")

In einigen anderen Antworten ging es um Editorfunktionen, mit deren Hilfe Sie den Typ einer Variablen beim Bewegen der Maus erkennen konnten. Meiner Meinung nach sind auch diese problematisch für die Code-Sicherheit . Ich glaube, sie waren nur für das Refactoring gedacht , ebenso wie viele andere Funktionen (wie das Falten von Funktionen) und sollten nicht für neuen Code verwendet werden.

ZJR
quelle
2

Ich denke, die Gründe für die Nichtverwendung der ungarischen Schreibweise wurden von anderen Plakaten gut abgedeckt. Ich stimme ihren Kommentaren zu.

Bei Datenbanken verwende ich die ungarische Notation für DDL-Objekte, die nur selten in Code verwendet werden, ansonsten aber in Namespaces kollidieren würden. Dies ist hauptsächlich darauf zurückzuführen, dass Indizes und benannte Einschränkungen mit ihrem Typ vorangestellt werden (PK, UK, FK und IN). Verwenden Sie eine konsistente Methode, um diese Objekte zu benennen, und Sie sollten in der Lage sein, einige Überprüfungen durchzuführen, indem Sie die Metadaten abfragen.

BillThor
quelle
Ich finde das oft der Fall, wenn ich eine Tabelle mit IDs habe. Wenn ich TABLE SomeStringById(int somestringId, varchar somestring)den Index drauf habe wäre das auch logisch SomeStringByIdaber das verursacht eine Kollision. Also nenne ich es idx_SomeStringById. Um dem Beispiel zu folgen, mache ich es idx_SomeStringByValuenur, weil es dumm ist, das idx_eine und nicht das andere zu haben.
CorsiKa
1

Der Grund, warum dies vermieden wird, ist, dass Systeme in Ungarn gegen DRY verstoßen (das Präfix ist genau der Typ, den der Compiler und (eine gute) IDE ableiten können).

Apps ungarischen OTOH Präfixe mit der Verwendung der Variablen (dh scrxMouse ist Axtkoordinate auf dem Bildschirm Dies kann ein Int, Short, Long oder sogar ein benutzerdefinierter Typ sein (Typedefs können Sie sogar leicht ändern))

das missverständnis von systemen ist das, was ungarisch als best practice zerstört

Ratschenfreak
quelle
2
Ich muss widersprechen - was das Ungarische als "Best Practice" zerstört hat, ist, dass es nie in der Nähe der besten (oder sogar der besten) Praxis war.
Jerry Coffin
2
@ Haylem: Ich habe die Artikel und das Originalpapier von Simonyi gesehen und den Code gelesen. In jeder Hinsicht ist es eine schlechte Idee, die niemals das Licht der Welt erblicken sollte.
Jerry Coffin
1
Es muss nicht unbedingt gegen DRY in einer dynamischen Sprache verstoßen. es ist nur unidiomatisch. TROCKEN ist nicht unbedingt immer gut; Beispiel: C-Makros.
Longpoke
3
IMO, was Ungarisch "zerstört" hat, ist die Tatsache, dass selbst die "Absicht" im Vergleich zur Verwendung beschreibender Namen nicht nützlich ist , obwohl, um fair zu sein, als Ungarisch geschaffen wurde, es keine Bewegung gab, um lesbaren Code zu haben ...
Wayne Molina
1
@Wayne M: "Beschreibende Namen" ist leicht zu sagen, wenn Compiler es Ihnen im Wesentlichen erlauben, einen Aufsatz für einen Variablennamen zu verwenden. Wenn die Länge des Bezeichnernamen tatsächlich auf einen niedrigen begrenzt war, ziemlich willkürlicher Wert (ich glaube , eine gemeinsame Grenze acht oder zehn Zeichen waren nicht , dass vor extrem lange, ich erinnere mich scheinen , dass Borland Turbo C 2 auch eine hatte Konfigurationsoption für die Die maximale Länge eines Bezeichnernamens!), die Kodierung nützlicher Informationen in einem Namen war nur ein kleines bisschen kniffliger ...
ein Lebenslauf vom
1

Nehmen wir an, wir haben eine Methode wie die folgende (in C #):

int GetCustomerCount()
{
    // some code
}

Nun nennen wir es im Code so:

var intStuff = GetCustomerCount();
// lots of code that culminates in adding a customer
intStuff++;

Das Int sagt uns nicht viel. Die bloße Tatsache, dass etwas ein Int ist, sagt uns nicht, was darin enthalten ist. Nehmen wir stattdessen an, wir nennen es so:

var customerCount = GetCustomerCount();
// lots of code that culminates in adding a customer
customerCount++;

Jetzt können wir sehen, was der Zweck der Variablen ist. Würde es etwas ausmachen, wenn wir wissen, dass es ein Int ist?

Der ursprüngliche Zweck von Ungarisch war jedoch, dass Sie so etwas tun:

var cCustomers = GetCustomerCount();
// lots of code that culminates in adding a customer
cCustomers++;

Dies ist in Ordnung, solange Sie wissen, wofür c steht. Aber Sie müssten eine Standardtabelle mit Präfixen haben, und jeder müsste sie kennen, und alle neuen Leute müssten sie lernen, um Ihren Code zu verstehen. Während customerCountoder countOfCustomersist auf den ersten Blick ziemlich offensichtlich.

Ungarisch hatte in VB zuvor einen bestimmten Zweck Option Strict On, da in VB6 und früheren Versionen (und in VB .NET mit Option Strict Off) VB Typen erzwingen würde. Sie können dies also tun:

Dim someText As String = "5"
customerCount = customerCount + someText

Das ist schlecht, aber der Compiler würde es Ihnen nicht sagen. Wenn Sie also Ungarisch verwenden, haben Sie zumindest einen Hinweis darauf, was passiert ist:

Dim strSomeText As String = "5"
intCustomerCount = intCustomerCount + strSomeText  // that doesn't look right!

In .NET ist dies bei statischer Typisierung nicht erforderlich. Und Ungarisch wurde zu oft als Ersatz für eine gute Benennung verwendet. Vergessen Sie Ungarisch und wählen Sie stattdessen gute Namen.

Kyralessa
quelle
1

Ich habe viele gute Argumente dagegen gefunden, aber eines habe ich nicht gesehen: Ergonomie.

In früheren Zeiten, als Sie nur string, int, bool und float hatten, hätten die Zeichen sibf ausgereicht. Aber mit string + short fangen die Probleme an. Verwenden Sie den ganzen Namen für das Präfix oder str_name für string? (Während Namen fast immer Zeichenfolgen sind - oder?) Was ist mit einer Street-Klasse? Die Namen werden immer länger, und selbst wenn Sie CamelCase verwenden, ist es schwer zu sagen, wo das Typpräfix endet und wo der Variablenname beginnt.

 BorderLayout boderLayoutInnerPanel = new BorderLayout ();
 panelInner.addLayout (borderLayoutInnerPanel);

Okay - Sie können Unterstriche verwenden, wenn Sie sie noch nicht für etwas anderes verwenden, oder CamelCase, wenn Sie so lange Unterstriche verwendet haben:

 BorderLayout boderLayout_innerPanel = new BorderLayout ();
 panel_inner.addLayout (borderLayout_innerPanel);

 Border_layout boder_layoutInner_panel = new Border_layout ();
 panelInner.add_layout (border_layoutInner_panel);

Es ist ungeheuerlich und wenn du es konsequent tust, wirst du haben

 for (int iI = 0; iI < iMax-1; ++iI)
     for (int iJ = iI; iJ < iMax; ++iMax) 
          int iCount += foo (iI, iJ); 

Entweder werden Sie unbrauchbare Präfixe für triviale Fälle verwenden, wie z. B. Schleifenvariablen oder count. Wann haben Sie kürzlich einen Short oder einen Long für einen Counter verwendet? Wenn Sie Ausnahmen machen, verlieren Sie oft Zeit und überlegen, ob Sie ein Präfix benötigen oder nicht.

Wenn Sie viele Variablen haben, werden diese normalerweise in einem Objektbrowser gruppiert, der Teil Ihrer IDE ist. Wenn nun 40% mit i_ für int und 40% mit s_ für string beginnen und sie alphabetisch sortiert sind, ist es schwierig, den signifikanten Teil des Namens zu finden.

Benutzer unbekannt
quelle
1

Der einzige Ort, an dem ich immer noch regelmäßig entweder ungarische oder analoge Suffixe verwende, ist in Kontexten, in denen dieselben semantischen Daten in zwei verschiedenen Formen vorliegen, wie z. B. Datenkonvertierung. Dies kann in Fällen der Fall sein, in denen mehrere Maßeinheiten vorhanden sind oder in denen mehrere Formen vorhanden sind (z. B. Zeichenfolge "123" und Ganzzahl 123).

Ich finde die Gründe, die hier angeführt wurden, nicht zwingend, um anderen kein Ungarisch aufzuzwingen , sondern nur als Andeutung, um über Ihre eigene Praxis zu entscheiden.

Der Quellcode eines Programms ist eine eigene Benutzerschnittstelle - dem Betreuer werden Algorithmen und Metadaten angezeigt - und Redundanz in Benutzerschnittstellen ist eine Tugend, keine Sünde . Sehen Sie sich zum Beispiel die Bilder in " Das Design alltäglicher Dinge " an und schauen Sie sich die Türen mit der Aufschrift "Push" an, die so aussehen, als würden Sie sie ziehen, und die Bierzapfstellen, die die Bediener an den wichtigen Kernreaktorsteuerungen gehackt haben, weil sie irgendwie "herumschwebten" sie in der IDE "war nicht gut genug.

Das "Just Hover in a IDE" ist kein Grund, Ungarisch nicht zu verwenden - nur ein Grund, warum manche Leute es möglicherweise nicht nützlich finden. Ihr Kilometerstand kann abweichen.

Die Idee, dass Ungarisch beim Wechsel der Variablentypen einen erheblichen Wartungsaufwand verursacht, ist albern - wie oft wechseln Sie die Variablentypen? Außerdem ist das Umbenennen von Variablen ganz einfach:

Verwenden Sie einfach die IDE, um alle Vorkommen umzubenennen. -Gander, antwortet auf Goose

Wenn Ungarisch Ihnen wirklich hilft, schnell einen Code zu finden und ihn zuverlässig zu pflegen, verwenden Sie ihn. Wenn nicht, dann nicht. Wenn andere Ihnen sagen, dass Sie sich in Bezug auf Ihre eigenen Erfahrungen geirrt haben, würde ich vorschlagen, dass sie wahrscheinlich diejenigen sind, die im Irrtum sind.

Ed Staub
quelle