Ich habe das Forum durchsucht, aber ich konnte keine Antworten finden, warum es vermieden werden sollte, nur warum es keine Wunderwaffe ist. Ich denke also nicht, dass diese Frage ein Duplikat ist.
Gibt es einen GÜLTIGEN Grund, warum ich Systemungarisch verlernen sollte, an das ich gewöhnt bin?
Bisher sehe ich die folgenden Vorteile bei der Verwendung:
- Konsistente Benennung von Variablen
- Sie sehen Typ ohne Suche (Intellisense ist die Hälfte der Zeit tot / indiziert, daher ist dies immer noch ein gültiger Grund)
- Die Semantik kann immer noch in den zweiten Teil des Namens gepackt werden
Und folgende Nachteile:
- Es nervt manche Leute (keine Ahnung warum)
- Wenn der Typ geändert wird, stimmt der Typ möglicherweise nicht mit der Benennung der Variablen überein.
Warum also:
vector<string> vecCityNames;
wstring strCity = L"abc";
//more code here
vecCityNames.push_back(strCity);
ist schlimmer als:
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
sein ,vectStringCityNames
so viel für Ihre konsequente Argumentation, und diese „Frage“ ist eher ein rant als alles andere, haben Sie Ihre Meinung, die aus dieser geschlossen werden sollte.cityNames.push_back(city)
ist ziemlich klar. Es ist eine Liste von Städtenamen und Sie fügen einen hinzu.Antworten:
Früher habe ich es benutzt (vor vielen Jahren) und ich weiß es nicht mehr. Der Hauptgrund ist, dass es in den OO-Sprachen mit starker Typisierung (C ++, Java) überflüssig ist, die ich zufällig die meiste Zeit meiner Karriere genutzt habe. Wenn ich meine Typen in diesen Sprachen gut definiere, kann und wird der Compiler die Typensicherheit für mich erzwingen. Alle Namenspräfixe sind also nur Unordnung, wodurch die Namen länger werden und somit schwerer zu lesen und zu suchen sind.
In jedem gut geschriebenen OO-Programm sind die meisten Ihrer Variablen (Verweise auf) benutzerdefinierte Typen. Wenn Sie diesen denselben allgemeinen Tag voranstellen (wie
o
für "object"), profitieren Sie nur von den Nachteilen. Wenn Sie ihnen jedoch typspezifische Tags voranstellen, geraten Sie in ein Labyrinth, in dem Sie versuchen, verschiedene Abkürzungen für tausend verschiedene Typen mit häufig ähnlichen Namen * zu finden und daran zu denken, sie alle zu ändern, wenn sich ein Typ oder sein Name ändert (was bedeutet) nicht selten in einem gut gepflegten Programm).Dies gilt natürlich nicht für Nicht-OO-Sprachen und möglicherweise auch nicht für schwach und / oder dynamisch typisierte Sprachen (ich habe keine Erfahrung mit diesen Sprachen, abgesehen von C). Weder für suboptimale Editoren / IDEs ohne ein verwendbares IntelliSense (oder sein lokales Äquivalent). Und das sind nur meine 2 Cent. Wenn also die ungarische Notation für Ihr Team und Ihr Projekt funktioniert, entscheiden Sie sich dafür. Es ist wichtig , dass Sie sich vor Projektbeginn darauf einigen (und auch auf einen einheitlichen Codierungsstil im Allgemeinen) und ihn jederzeit konsistent halten.
* Nur eine kurze Liste aus unserem aktuellen Projekt: wir haben
Charge
,ChargeBreakdown
,ChargeCalculator
,ChargeDAO
,ChargeDTO
,ChargeLineHelper
,ChargeMaps
,ChargePair
undChargeType
, unter anderem. Darüber hinaus haben wir auchContract
s,Countrie
s,Checkout
s,Checkin
s ... und das ist nur der Buchstabe C, in einem Projekt , das wahrscheinlich nicht einmal „vernünftige Größe“ der OP genannt würde.Disclaimer: Ich bin eigentlich ein Ungar, also glaube ich, dass ich mit Autorität zu diesem Thema sprechen kann ;-)
quelle
iPos
oderfAmount
möglicherweise tolerierbare Variablen. Versuchen Sie jedoch, auf einer Codebasis zu arbeiten, bei der jeder Objektvariablen ein redundantes Präfix mit sechs Buchstaben zugewiesen wird, das Sie lediglich darüber informiert, dass es sich um einen "Zeiger auf eine Struktur" handelt.char[]
von a gehaltenenStringBuilder
), und Verweisen auf Instanzen, die möglicherweise nicht mutiert sind, aber nicht geteilt werden kann mit Dingen geteilt werden, die sie nicht mutieren (z. B. diechar[]
vonString
, die von mehrerenString
Instanzen geteilt werden können). Beide Felder sind vom selben Typchar[]
, enthalten aber sehr unterschiedliche Dinge. Viele Fehler im Zusammenhang mit der Veränderlichkeit stammen von ...Warum ist
std::vector<string> vecCityNames;
schlecht?Das Problem mit der ungarischen Notation, wie es normalerweise verwendet wird, ist, dass, wenn die Profilerstellung zeigt, dass Städtenamen lieber in a gehalten werden sollten
std::deque
, alle Variablennamen, die sich auf ein Objekt dieses Typs beziehen, plötzlich einen irreführenden Namen haben.Benennen Sie dann alle Variablen um? Haben Sie jemals versucht, dies in einem großen Projekt zu tun? Mit Murphys Hilfe (und der Typ ist dort unglaublich hilfsbereit) hat sicherlich irgendjemand irgendwo Variablen verwendet, die so etwas wie heißen.
deqCityNames
Ihre Änderungen machen den Build kaputt und Sie sitzen stundenlang da und fummeln an Code, den ein halbes Jahrzehnt lang niemand zu betrachten gewagt hat aus Angst, von einem giftigen Tier gebissen zu werden.Soweit ich jedoch weiß, bezeichnet das Präfix, wie Charles Simonyi Ungarisch formulierte, die semantische Verwendung der Variablen und nicht deren syntaktischen Typ . Das heißt, das richtige Präfix für Ihre Liste von Städtenamen, egal in welchem Typ es implementiert ist, wäre wahrscheinlich
listCityNames
(oderlstCityNames
, wennlist
es für Sie nicht kryptisch genug ist).Ich halte dieses Präfix jedoch für überflüssig, da der Plural ("Namen") bereits besagt, dass es sich um eine Ansammlung von Städten handelt. Fazit: Wenn Sie Ihre Identifikatoren sorgfältig auswählen, wird die ungarische Notation selten benötigt. OTOH, so wie es allgemein verwendet wird, fügt es auf lange Sicht tatsächlich dem Code Schaden zu.
quelle
typedef
ist ein Tool stark unterbewertetvecCityNames
zudeqCityNames
in ein paar hundert Dateien und Sie tun das gleiche.Aus irgendeinem Grund scheinen die hier gegebenen Antworten die ungarische Notation zu begründen, ohne sie direkt zu formulieren. Die ungarische Notation ist nützlich, um Typinformationen (im typentheoretischen Sinne ) hinzuzufügen, wenn dies in der Sprache selbst schwierig ist . Es ist in der Regel nicht so schwierig, C ++ oder Javas Typensystem so zu verwenden, dass die ungarische Notation (wie gewöhnlich beschrieben) völlig überflüssig ist, und dies hat wahrscheinlich zu dem Gegenschlag geführt - es fügt Programmiererarbeit hinzu Diese Annotationen in all unseren variablen Naes beizubehalten, bietet jedoch nur einen geringen bis keinen zusätzlichen Wert (und kann sogar Schaden anrichten, da der Code überladener aussieht).
Wenn man andererseits die Verwendung der ungarischen Notation einschränkt, um Informationen zu tippen (wiederum im typentheoretischen Sinne ), ist dies nicht der Fallnatürlich von der Sprache eingekapselt, dann kann es sehr nützlich sein. Beispielsweise übergeben C und C ++ Array-Referenzen als Zeigertypen, aber Array-Referenzen und Zeiger müssen unterschiedliche Operationen ausführen: Arrays können über das erste Element hinaus indiziert werden, Zeiger hingegen nicht. Dies sind nützliche Informationen, die dem Typsystem verloren gehen, sobald ein Array als Argument an eine Funktion übergeben wird. Aus diesem Grund haben wir in unserer Gruppe Annotationen für Variablennamen in C- und C ++ - Code übernommen, um zu unterscheiden, ob eine Zeigervariable tatsächlich ein Zeiger auf ein einzelnes Element oder ein Zeiger auf ein Array ist. Die Annahme dieser Konvention war teilweise verantwortlich für eine große Reduzierung des Auftretens von Speicherbeschädigungsproblemen in unserer Codebasis.
quelle
dw
gegencb
.) Es ist nicht so, dass seine ursprüngliche Form in OO-Sprachen weniger hilfreich wäre: Ein Index ist immer noch ein Index, auch wenn er in einem Klassentyp und nicht in einem eingebauten Typ gespeichert ist.Der Grund, warum es mich ärgert, ist, dass es ein kleiner Geschwindigkeitsschub bei jeder einzelnen Kennung ist, der mein visuelles Scannen des Codes verlangsamt. Es ist mAs, wenn Sie ZUM LESEN DES DEUTSCHEN TEXTES MÖCHTEN.
quelle
Hass ist ein zu starkes Wort, IMO. Sie können Ihren Code so schreiben, wie Sie möchten. Ich bevorzuge es einfach, in meinem eigenen Code keine ungarische Notation zu verwenden, und wenn ich die Wahl habe, möchte ich es auch lieber nicht lesen oder damit im Code anderer Leute arbeiten müssen.
Sie haben gefragt, warum manche Leute die ungarische Notation als störend empfinden. Ich kann nicht für andere sprechen, aber die Gründe, die mich ärgern, sind:
Es ist hässlich. Ungarisch nimmt völlig vernünftige Namen und stellt das voran, was einem Code entspricht. Wenn Sie diesen Code erst einmal verinnerlicht haben, ist das sicher sinnvoll, aber für Anfänger sieht es so aus, als hätte jemand den C ++ - Namensverwalter für meinen Quellcode aktiviert.
Es ist überflüssig. Die Deklaration einer Variablen legt ihren Typ fest. Ich habe nicht das Bedürfnis, diese Information im Variablennamen zu wiederholen. Dies ist nicht in jeder Sprache der Fall: In Perl definieren beispielsweise Zeichen wie @ oder $ vor dem Variablennamen im Wesentlichen den Typ der Variablen, sodass Sie keine andere Wahl haben, als sie zu verwenden.
Es löst ein Problem, das ich nicht habe. Methoden und Funktionen sollten nicht so lang sein, dass Sie nach der Deklaration einer lokalen Variablen oder eines Parameters suchen müssen, und sie sollten nicht so viele Variablen umfassen, dass Sie Probleme haben, den Überblick darüber zu behalten, was was ist. Auch hier hilft es, lokale Variablen in der Nähe des Codes zu deklarieren, der sie verwendet. C-Compiler der Vergangenheit erforderten, dass alle lokalen Variablen zu Beginn der Funktion deklariert wurden. Diese Einschränkung wurde jedoch vor langer Zeit aufgehoben.
Es ist unvollständig. Die ungarische Notation wurde für eine Sprache (BCPL) erfunden, die kein Typensystem hatte, und wurde später in einer Sprache (C) mit einer relativ begrenzten Anzahl von einheimischen Typen häufig verwendet. IMO funktioniert es nicht gut mit Sprachen wie C ++ oder Java, die über umfangreiche Typsysteme verfügen. Warum sollte ich ein Präfix verwenden, um den Typ einer Variablen anzugeben, die ein nativer Typ ist, wie char [], aber keine Klasse? Wenn ich Präfixe wie
vec
für Klassen erfinde , wird eine große Hierarchie von Präfixen parallel zu meiner Klassenhierarchie erstellt. Wenn Ihnen das gefällt, können Sie es gerne tun. wenn ich nur daran denke, bekomme ich Kopfschmerzen.Es ist zweideutig , zumindest so wie ich es verstehe. Was ist der Unterschied zwischen
szFoo
undpszFoo
? Die erste ist eine nullterminierte Zeichenfolge, und die zweite ist ein Zeiger auf eine nullterminierte Zeichenfolge. Aber in C oder C ++ ist, soweit ich weiß, jede Zeichenkettenvariable effektiv ein Zeiger. Sind sie also gleich oder nicht? Welches soll ich verwenden? Die eigentliche Antwort spielt wirklich keine Rolle - der Punkt ist, dass ich die Antwort nicht anhand der Notation erkennen kann, die mir helfen soll, diese Art von Fragen zu vermeiden. Die Deklaration der Variablen muss dagegen eindeutig sein, da sie vom Compiler verwendet wird.Das sind die Dinge, die mich an der ungarischen Notation ärgern . Auch als Gruppe glaube ich nicht vollständig zu erklären, warum Ungarisch weitgehend aufgegeben wurde. Hier sind die drei Hauptgründe, warum die meisten Programmierer kein Ungarisch verwenden:
Es gibt keinen zwingenden Grund, es zu benutzen. Siehe Punkt 3 und 4 oben. Ich könnte wahrscheinlich mit den Ärgernissen leben, wenn Ungarisch einen großen Vorteil gegenüber dem Verzicht auf Ungarisch bietet, aber ich sehe keinen, und anscheinend tun es die meisten anderen auch nicht. Vielleicht war das Beste an Ungarisch, dass es eine weit verbreitete Konvention war, und wenn Sie sich an den Standardsatz halten, können Sie davon ausgehen, dass andere Programmierer mit ähnlichen Fähigkeiten die Notation verstehen.
Erhöhter Einfluss von Unternehmen, die nicht von Microsoft stammen. Es ist wahrscheinlich fair zu sagen, dass die meisten Programmierer, die die ungarische Notation verwendeten, dies taten, weil Microsoft auf diese Weise Code schrieb und es oft einfacher ist, mit dem Fluss umzugehen. Unternehmen wie Google und Apple haben heute viel, viel größere Einflussbereiche als früher, und mehr Programmierer als je zuvor greifen auf die Stile dieser und anderer Unternehmen zurück, die Ungarisch größtenteils meiden. (Es ist nur fair, darauf hinzuweisen, dass Sie immer noch einige Überbleibsel sehen, z. B. verwenden sowohl Google als auch Apple häufig ein "k" -Präfix für konstante Namen.)
Microsoft selbst hat Ungarisch aufgegeben. Wenn Sie den Abschnitt Allgemeine Namenskonventionen von Microsoft in den Codierungsrichtlinien lesen, werden Sie feststellen, dass in Fettdruck Folgendes steht: Verwenden Sie keine ungarische Notation.
Ein triftiger Grund, die ungarische Notation nicht mehr zu verwenden, ist daher:
Die Popularität der ungarischen Notation ist so weit zurückgegangen, dass die Konvention nicht mehr hilfreich ist. Heutzutage verwenden weit weniger Programmierer Ungarisch oder verstehen es sogar, und die Konvention ist daher viel weniger effektiv darin, die Informationen zu vermitteln, die sie vermitteln sollen. Wenn Sie es für nützlich halten, Code in Ihre eigenen persönlichen Projekte zu schreiben, gibt es wenig Grund, damit aufzuhören. Wenn Sie jedoch Code als Teil eines Teams schreiben, das kein Ungarisch verwendet, kann dies zu einer Mauer zwischen Ihnen und dem Rest des Teams werden, anstatt zu einer erfolgreichen Kommunikationsstrategie.
quelle
szFoo
undpszFoo
"? Eine davon istchar*
, die anderechar**
, nahm mich 0,25 Sekunden den Unterschied zu erkennen. Versuchen Sie, dies mit Intellisense zu übertreffen.pnFoo
wäre wahrscheinlichint*
nichtint**
, also muss man wissen, dass dassz
auch einen Zeiger bedeutet. Ich bin sicher, es ist kein großes Problem für die begrenzte Anzahl von Typen, die ungarische Präfixe festgelegt haben, aber in jedem großen Projekt gibt es eine definierte Typenzahl in Tausenden. Ich weiß nichts über Intellisense, aber die IDEs haben sich in den letzten 25 Jahren stetig verbessert, und ich gehe davon aus, dass sich dieser Trend fortsetzt.Wenn ich alle meine Variablen nach den Zeichen von The Simpsons benenne, ist das auch konsistent, aber ist es ein Vorteil?
Dies ist der einzig gültige Grund, der auf der Schwäche eines bestimmten Werkzeugs beruht ...
Das ist kein Vorteil; Sie behaupten lediglich das Fehlen eines ( massiven ) Nachteils.
quelle
Die IDE teilt mir trivialerweise mit, um welchen Typ es sich bei einer Variablen handelt, wenn ich mit der Maus darüber fahre. Warum also die Mühe machen, diese Informationen zu duplizieren? Grundsätzlich ist die ungarische Systemnotation eine Verletzung von DRY mit all den damit verbundenen Fallstricken. Wenn diese Informationen in einer modernen Umgebung einfach zugänglich sind, gibt es keinen Grund, diesen Preis zu zahlen.
Konsistenz ist an sich kein Vorteil. Sie nicht mit dem Typ zu benennen, ist ebenfalls konsistent. Sie würden nur Inkonsistenzen haben, wenn nur einige Variablen ihren Typ im Namen hätten. Und Semantik in den zweiten Teil zu packen ist einfach "Nun, es ist nicht so schlimm.", Jeder andere darf den ganzen Namen für Semantik verwenden. Sie haben keine wirklichen Vorteile aufgelistet.
quelle
Ein weiterer Punkt bei traditionellen Formen der ungarischen Notation ist, dass es sich normalerweise um Präfixe handelt. hier gibt es imho 2 probleme:
1) Ein menschlicher Leser möchte im Allgemeinen zuerst die wichtigsten Informationen, in den meisten Formen des Ungarischen sind die verschlüsselten Informationen vermutlich weniger wichtig als der Name selbst.
2) Präfixe bewirken eine lexikalische Sortierung. Wenn Sie zum Beispiel ein Präfix verwenden, um Schnittstellen oder Klassen zu kennzeichnen, und Ihre IDE eine sortierte Liste davon bereitstellt, werden verwandte Klassen / Schnittstellen in dieser Liste getrennt.
quelle
Es ist klar, dass dies auf Meinungen zurückzuführen ist, sodass es schwierig sein wird, hier mit Fakten zu arbeiten. Persönlich finde ich, dass das Argument für die ungarische Notation in stark typisierten, objektorientierten Sprachen etwas dünn ist. Nach meiner Erfahrung können OO-Anwendungen die Komplexität meistern, indem sie die Klassen kohärent und prägnant halten. Dasselbe gilt für Funktionen. Dies bedeutet, dass Sie, wenn alle anderen Dinge gleich sind, am Ende Folgendes haben:
Wenn Sie nun die ungarische Notation verwenden möchten, müssen Sie entscheiden, ob Sie sie allgemein anwenden oder nur für bestimmte privilegierte Typen und Klassen (wie z. B. Kernbibliotheksklassen) verwenden möchten. Letzteres ergibt für mich keinen Sinn, und Ersteres führt zu dem "Labyrinth des Versuchs, verschiedene Abkürzungen für tausend verschiedene Typen zu finden", auf das sich Péter Török bezog. Dies bedeutet, dass die Pflege der Abkürzungslisten einen erheblichen Aufwand bedeutet und in der Regel "konsistente Variablennamen" nicht mehr angezeigt werden.
Der zweite Punkt zu kürzeren Methoden bedeutet, dass Sie in den meisten Fällen nicht Hunderte von Codezeilen durchgehen müssen, um den Typ einer Variablen zu überprüfen. Wenn Sie Variablen etwas sorgfältiger benennen, werden einige Ihrer anderen Fragen beseitigt - z . B.
cityName
vs.city
Ich würde hoffen, dasscityName
das kein Schwimmer ist :)Was den Grund angeht, warum es die Leute nervt - auch dies ist wahrscheinlich darauf zurückzuführen, dass man sich daran gewöhnt hat oder nicht. Aber als jemand, der nicht daran gewöhnt ist, kann ich Ihnen sagen, dass die Verwendung der ungarischen Notation den Codefluss für meine Augen unterbricht und es schwieriger macht, schnell zu lesen. Zusammenfassend sage ich nicht, dass es keinen Wert hat (obwohl ich einige seiner Nachteile in Bezug auf Refactoring usw. nicht besprochen habe), ich sage, dass sich der Aufwand für stark typisierte OO-Sprachen nicht lohnt.
quelle
Ich weiß es nicht im Kontext von C ++, aber in der Java / C # -Welt hätte ich lieber aussagekräftige Namen, die entweder eine Domänensprache oder einen Kontext vermitteln, als mir zu sagen, dass
strFirstName
es sich um einen String handelt. Es sollte offensichtlich sein, dass es sich um eine Zeichenfolge handelt, oder der Name muss überarbeitet werden, um eine bessere Absicht zu vermitteln. Wenn du ein Präfix benötigen, um zu wissen, mit welcher Art von Namen Sie arbeiten, ist Ihre Benennung meiner Meinung nach inkonsistent, nicht aussagekräftig genug oder ausgesprochen falsch. In modernen Sprachen bevorzuge ich immer längere Namen, die keine Mehrdeutigkeit hinterlassen als vage oder mehrdeutige Namen.Das einzige Mal, dass ich Ungarisch verwende, ist für ASP.NET-Steuerelemente, und das heißt, IA) muss nicht wirklich lange wie
CustomerFirstNameTextBox
versus eingebentxtCustomerFirstName
, und B) Intellisense sortiert alle Steuerelementtypen. Ich fühle mich "dreckig", obwohl ich noch keinen besseren Weg gefunden habe.quelle
Meh - es geht wirklich um persönliche Vorlieben, egal wie sehr man versucht, seine Entscheidungen zu rationalisieren. Ich persönlich halte mich an die Regel "When in Rome ..." und verwende Ungarisch in Code, der häufig die Windows-API aufruft. Für plattformunabhängigen Code neige ich dazu, dem C ++ Standard Library-Stil zu folgen.
quelle
Die Antwort liegt in dieser Frage: Bitte sagen Sie mir, wie ich die folgenden Variablen benennen soll:
Fügen Sie zu diesen konstanten Zeichenfolgen Zeiger auf diese und konstante Zeiger auf diese hinzu.
quelle
szFoo
,wczFoo
,strFoo
,(w)strFoo
,strFoo
,bstrFoo
,bstrFoo
Die von Ihnen beschriebene Form der ungarischen Notation gefällt mir überhaupt nicht. Der Grund? Es ist in 90% der Fälle sinnlos.
Zum Beispiel ein bisschen (äquivalentes C ++. Tatsächlich in Delphi geschrieben) Code aus einem Legacy-Projekt, das ich ertragen muss:
... pRecord ist eine Variable vom Typ TRecordList.
TRecordList *pRecords[10];
Es ist eine Klasse, die aus einer orioerty namens FooMember besteht, die auf fFooMember ... oder mFooMember verweist, je nachdem, ob es sich um ein "Feld" oder ein "Mitglied" handelt (Hinweis: Sie sind dasselbe).
Probleme?
fFooMember
könnte so etwas wie FooMember_ sein, weil wir immer über die öffentliche Eigenschaft FooMember darauf zugreifen. pRecords? Es ist ziemlich offensichtlich, dass es ein Hinweis auf die Tatsache ist, dass Sie es überall dereferenzieren. TRecordList? Wann können Sie möglicherweise einen Typnamen und ein Objekt dieses Typs verwechseln? Der Compiler wird Sie anschreien und Typen werden fast an keiner Stelle verwendet, an der sich Objekte befinden (außer bei statischen Eigenschaften / Methoden).Jetzt gibt es einen Ort, an dem ich die ungarische Notation verwende. Hierbei handelt es sich um eine Vielzahl von UI-Variablen, die denselben Namen wie andere UI-Variablen oder reguläre Variablen haben.
Zum Beispiel, wenn ich ein Formular für Ihren Vornamen darauf hatte.
Ich hätte eine Klasse namens FirstNameForm. Darin lblFirstName und txtFirstName für die Bezeichnung bzw. das Textfeld. Und eine öffentliche FirstName-Eigenschaft zum Abrufen und Festlegen des Namens im Textfeld.
Dies könnte auch mit FirstNameLabel und FirstNameTextBox gelöst werden, aber ich finde, es wird lange zu tippen. Vor allem bei sowas wie GenderDropDownList und so.
Im Grunde genommen ist die ungarische Notation auf systematischer Ebene bestenfalls ärgerlich und im schlimmsten Fall schädlich (da die anderen Antworten Probleme mit Refactoring und Konsistenz aufzeigen).
quelle