namespace cpp

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


lernen:naming

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

lernen:naming [2014-07-13 16:15] (aktuell)
Zeile 1: Zeile 1:
 +====== Schall und Rauch --- Das Spiel mit den Namen ======
 + 
 +>    He writes a, he says b, he means c; but it should be d. [...]
 +>    After all, you can learn something from this traditional mathematics professor.
 +>>​--- ​   G. Polya [How to solve it]
 +
 +Gibt es eine Antwort auf die Frage: ​
 +Ist '''​name(neuer_name)'',​ ''​setName(neuerName)''​ oder 
 +''​m_fvSetName(lpszNeuerName)''​ besser? Und falls ja, wie lautet sie?
 +
 +===== Der Name des Spiels: Namenskonventionen. =====
 +
 +Konvention heißt Übereinkunft,​ Sitte, soziale Regel. ​
 +Um sich mit anderen verständigen zu können, ​
 +müssen die Kommunikationspartner Vereinbarungen treffen oder (unbewusst) ​
 +schon getroffen haben. Nichts ist ärgerlicher als fruchtlose Diskussionen, ​
 +in denen alle aneinander vorbei reden, ​
 +obwohl sie vielleicht sogar dasselbe Ziel verfolgen. Sie erkennen nicht, ​
 +dass sie nur unterschiedliche Wörter für dasselbe benutzen (Synonyme) oder, 
 +schlimmer, dasselbe Wort mit jeweils anderer Bedeutung (Homonyme). ​
 +In solchen Fällen hilft, kooperative Gesprächspartner vorausgesetzt, ​
 +meist nur die Rückfrage: Was meinst du mit ... ? 
 +Solche Begriffsbestimmungen sollten am Anfang stehen.
 +
 +Wenn wir sprechen, tragen aber nicht nur die Laute der Wörter Bedeutung. ​
 +Wir betonen verschiedene Dinge unterschiedlich. Der Tonfall ist wichtig. ​
 +Sehen wir den Gesprächspartner,​ drücken wir auch mit Gesichtszügen (Mimik) ​
 +und Körperhaltung (Gestik) beim Sprechen etwas aus. 
 +Das Fehlen solcher Zusatzinformationen bei elektronischer Kommunikation ​
 +(eMail, Chat) hat zu Smileys und Emoticons geführt, ​
 +die nur der Eingeweihte versteht:
 +
 +  Videohandys werden nicht funktionieren /g/, 
 +  weil darauf nur Ohren zu sehen sind *rotfl* Ich gehe zu |---| :-( .
 +
 +Wenn wir schreiben, kann nur ein Teil davon nachgebildet werden. ​
 +Dafür haben wir andere Möglichkeiten:​ Schriftartwechsel,​ Großschreibung ​
 +(Sie oder sie), Absatzbildung,​ Einrückung,​ Anführungszeichen,​ Klammern, ​
 +Fußnoten((In C++ würde der Fußnote vermutlich am ehesten ein Kommentar entsprechen.)). ​
 +Nicht umsonst wird um die Rechtschreibung und um gutes Layout erbittert gestritten. ​
 +Beide transportieren Inhalte. Beide sind Fragen der Übereinkunft. ​
 +Beides sind auch Fragen des Geschmacks, über den sich bekanntlich erbittert, ​
 +trefflich oder gar nicht streiten lässt, ​
 +je nach Standpunkt und Definition des Begriffes Geschmack.
 +
 +Wie wichtig eine gute Notation ist, zeigt die Entwicklung der Zahlensysteme: ​
 +ägyptisch mit Hieroglyphen,​ attisch und milesisch mit griechischen und 
 +semitischen,​ römisch mit lateinischen Zahlbuchstaben, ​
 +babylonisch mit Keilschrift (ein Basis-60-System), ​
 +chinesisch mit Bambusstäbchen,​ indisch-arabisch ​
 +(das uns geläufige Dezimal-Positionssystem mit der Null) 
 +oder das Dualsystem der Computer. Eine Zahl aufschreiben,​ geht in jedem System, ​
 +damit rechnen jedoch nicht immer gleich gut: 
 +Griechische Zahlen ließen sich wohl am besten durchstreichen ​
 +(so erfand Eratosthenes das Primzahlsieb), ​
 +Babylonier mussten das ganz große 1x1 bis 60 beherrschen ​
 +(als Keilschrift-Tafelwerk) und gingen dabei in die 
 +Brüche((Als der Turm zu Babel zu Bruch ging mangels Statiker, ​
 +erfanden sie die Bruchrechnung. Auch babylonische Bruchteile ​
 +wie 60 Minuten je 60 Sekunden sind uns daher überliefert.)), ​
 +Römer erfanden den Abakus und den Kalkül ​
 +("​rechenung auff der linien"​ mit Kalk-Steinchen = calculi), ​
 +heutige Studenten greifen bei "2 mal 3" reflexartig zum Taschenrechner, ​
 +für den sogar unser Zehnfingersystem zu kompliziert ist (Striche und Kringel genügen).
 +
 +Notation zählt. Notation macht den Unterschied. Auch wenn es "​nur"​ um Namen geht.
 +
 +Nicht alles ist in Programmiersprachen durch die Syntax festgelegt. ​
 +Ein gleiches äußeres Programmverhalten kann durch viele unterschiedliche ​
 +Programmentwürfe und Quelltexte erreicht werden. Je komplexer das Problem, ​
 +umso mehr Möglichkeiten gibt es. Quelltextaufteilung,​ Programmorganisation, ​
 +Formatierung und auch Namensgebung sind in C++ innerhalb gewisser Grenzen dem Anwender überlassen. ​
 +Über jedes dieser Teilgebiete lassen sich zusätzliche Empfehlungen, ​
 +Richtlinien und Standards errichten und erbitterte Debatten führen.
 +
 +Der einzelne Programmierer kann, sollte und wird sich entscheiden, ​
 +welcher Stil für sein Projekt geeignet ist. Wer "​keinen Stil" verfolgt, ​
 +schreibt dennoch "​irgendwie"​. Nur hat er die Kontrolle darüber aus der Hand gegeben. ​
 +Wer in ein Programmierteam eintritt, wird dort bestimmte Stilkonventionen vorfinden. ​
 +Nehme ich sie an? Arbeite ich dagegen? Können andere meinen Stil akzeptieren?​
 +
 +Einen Stil anzunehmen oder herauszubilden, ​
 +erfordert Auseinandersetzung mit den verschiedenen Möglichkeiten, ​
 +Wissen um die Hintergründe. Was kann dem Leser des Quelltextes ​
 +neben syntaktisch korrektem Verhalten noch mitgeteilt werden? ​
 +Bei jedem Stil gibt es Argumente, die dafür, und solche, die dagegen sprechen.
 +
 +Das gilt auch für so grundlegende Dinge wie die Wahl eines Namens. ​
 +Nicht nur Anfänger tun sich schwer, für bestimmte Daten eine Bezeichnung zu finden. ​
 +Dieses Zögern hat seinen Grund. ​
 +Aus psychologischen und ergonomischen Untersuchungen ist bekannt, ​
 +dass die Auswahlzeit proportional ist zum Logarithmus der Anzahl der zur Wahl stehenden Möglichkeiten. ​
 +Zur Auswahl stehen 52 kleine und große Buchstaben, ​
 +der Unterstrich und 10 Zifferzeichen,​ diese jedoch nicht am Anfang. ​
 +Ein Name darf beliebig lang sein. Wer die Wahl hat, hat die Qual. 
 +Eine treffende Bezeichnung ist ein Glücksfall. ​
 +Überlassen Sie Ihr Glück nicht dem Zufall, wählen Sie Bezeichner mit Stil. 
 +Namenskonventionen können dazu beitragen. ​
 +Im Englisch-Wörterbuch steht convention (Sitte) hinter convenience ​
 +(Annehmlichkeit,​ Zweckmäßigkeit). ​
 +Wählen Sie einen zweckmäßigen Stil. Wählen Sie mit Bedacht.
 +
 +Ich werde Ihnen keine fertige Richtlinie vorgeben. ​
 +Davon gibt es im Internet schon genug (Taligent, GNU, Microsoft, ...). 
 +Sie werden mit Beispielen konfrontiert. ​
 +Die Gestaltungsmöglichkeiten sind vielfältig. ​
 +Jede Art der Entscheidung wird mit einem Dafür und Dagegen versehen. ​
 +Wenn ich "​dafür"​ schreibe, heißt das nicht unbedingt, dass ich "​dafür"​ bin. 
 +Prüfen Sie, ob die Argumente für Sie stichhaltig erscheinen. ​
 +Finden Sie bessere Begründungen. Entscheiden Sie sich dann. 
 +Nicht immer ist es ein "gutes Beispiel"​. Manchmal lässt sich die Entscheidung so, 
 +aus dem Zusammenhang gerissen, nicht treffen. Finden Sie treffendere Beispiele. ​
 +Ebenso lassen verschiedene Kombinationen bilden. ​
 +Manche Stilentscheidungen sind miteinander vereinbar, andere nicht. ​
 +Manchmal gibt es mehr als zwei Möglichkeiten. ​
 +Sie müssen sich auch nicht immer nur dafür entscheiden oder immer nur dagegen ​
 +(der Geist, der stets verneint). Wichtig ist, 
 +dass Sie wissen und für sich selbst und vor anderen begründen können, ​
 +warum Sie eine Richtung vertreten. Nur dann besteht die Chance, ​
 +dass Sie andere überzeugen können. Seien Sie aber auch offen für Argumente anderer. ​
 +Versuchen Sie, diese zu widerlegen. Demokratie muss Widerspruch aushalten. ​
 +Finden Sie bessere Argumente. Autorität entsteht durch Überzeugungskraft, ​
 +nicht durch Befehle.
 +
 +===== Namenwahl =====
 +==== Über kurz oder lang ====
 +
 +Programmierer sind faul. Sie mögen keine langen Namen. Ein Buchstabe reicht.
 +
 +<code cpp>
 +double a = 14, b = 0.25, c, d;
 +std::cin >> c;
 +d = 12*a+b*c;
 +</​code>​
 +**Pro:** Programmierer sind nicht (nur) faul. 
 +Beim Programmieren entsteht ein Schreibstau. Die Ideen entstehen schneller, ​
 +als sie niedergeschrieben werden können. ​
 +Daher der Drang zu möglichst wenigen Tastenanschlägen. ​
 +Solange die Namen nur in einem kleinem Bereich Bedeutung haben, ​
 +sind kurze Namen in Ordnung: ​
 +Typische Zählschleifen haben einen ganzzahligen (int) Schleifenzähler (Iterator) ​
 +namens ''​i''​ (auch als Index eines Feldes).
 +
 +**Kontra:** Ein typischer Hacker, ein typisches "​fire+forget"​-Programm ohne Entwurf. ​
 +Keiner ahnt, dass es sich hierbei um eine Stromrechnung handelt ​
 +(ehemaliger "​Dresdner Strom" 14/​25). ​
 +Nicht einmal ein Kommentar weist darauf hin, 
 +dass ''​a''​ der monatliche Grundpreis in DM, ''​b''​ der Arbeitspreis je kWh, 
 +''​c''​ die verbrauchten kWh und ''​d''​ der Betrag der Jahresrechnung in DM sind. 
 +Besser sind längere, beschreibende Namen.
 +
 +==== Abkürzungen und Verwechslungsgefahr ====
 +
 +Abkürzungen verschlechtern die Lesbarkeit.
 +
 +<code cpp>
 +  char hs, strg[] = "Cn U rd ths qckly?";​
 +  strcpy(strg, ​     "Ich kann das lesen"​);​
 +</​code>​
 +
 +**Pro:** Viele Namen der Standard-C-Bibliothek bestehen aus Abkürzungen, ​
 +aus historischen Gründen: ​
 +Die ersten Linker konnten nur 6 Zeichen auseinanderhalten. ​
 +Wissen Sie, was ''​sbrk()''​ heißt und bewirkt? ​
 +Schreiben Sie neue, beschreibende Namen aus. 
 +Das Kürzel ''​hs''​ kann viel zu vieles bedeuten: ​
 +has, head of string, haus, hose, hase (ich weiß von nichts). ​
 +Verkürzungen verringern die semantische Distanz; ​
 +die Gefahr von Verwechslungen mit ähnlich lautenden Namen wächst.
 +
 +**Kontra:** Das gilt nicht nur für Abkürzungen,​ siehe hose - hase. 
 +Vermeide generell ähnliche Namen. Vermeide auch gleiche Bezeichner. ​
 +Definiere Namen erst dort, wo sie gebraucht werden, so lokal wie möglich, ​
 +innerhalb geschweifter Klammern. C++ erlaubt das, C erlaubte es nicht. ​
 +Vermeide globale Variablen. ​
 +Je lokaler eine Variable ist, umso kürzer kann auch ihr Name sein.
 +
 +==== Unterstriche ====
 +
 +Unterstriche sind zu vermeiden.
 +<code cpp>
 +  int _error;
 +</​code>​
 +**Pro:** Unterstriche am Anfang oder Ende eines Namens ​
 +kommen häufig bei versteckten,​ systemabhängigen oder nicht portablen Teilen ​
 +innerhalb der Standardbibliothek vor. Vor allem Präprozessor-Makros, ​
 +Include-Wächter usw. sind so gekennzeichnet:​ ''​__FILE__'',​ ''​__cplusplus''​.
 +
 +**Kontra:** Lokale Variablen verdecken vordefinierte Namen. ​
 +Gegen ''​_tmp''​ ist nichts einzuwenden,​ sofern das kein Präprozessor-Makro ist. 
 +Falls doch, lässt sich eine lokale Variable leicht umbenennen.
 +
 +==== Durchkoppeln oder SmallTalk ====
 +
 +Für lange Namen aus mehreren Wörtern sind Unterstriche besser als große Wortanfänge.
 +
 +<code cpp>
 +int Anzahl_der_Woerter_je_Zeile;​
 +int smallTalkStilMitGrossenAnfangsbuchstaben;​
 +</​code>​
 +
 +**Pro:** Im Deutschen hat Groß- und Kleinschreibung grammatische Bedeutung. ​
 +Mit Unterstrichen statt Leerzeichen lassen sich solche Feinheiten nachbilden.
 +
 +**Kontra:** Ich schreibe englischen Quelltext, auch wenn es manchmal schwierig ist, 
 +das richtige englische Wort zu finden... ​
 +Beide Stile werden in unterschiedlichen Kreisen gepflegt. ​
 +Die Vermischung beider führt zu Chaos.
 +
 +==== Kryptische oder sprechende Namen ====
 +
 +Manche verwenden Namen von Figuren aus ihrem Lieblingsfilm oder -roman.
 +<code cpp>
 +std::​swap(Phouchg,​ Lounquaal);
 +</​code>​
 +**Pro:** Sie kennen die beiden nicht? Keine Panik! ​
 +Lesen Sie Douglas Adams' Hitchhikers'​ Guide to the Galaxy. ​
 +Außerdem: Kryptische Namen verführen nicht, das zu glauben, was da steht.
 +
 +**Kontra:** Lesen können Sie das Buch (nach der Arbeit). ​
 +Solange Sie aber kein Filmprogramm bauen, ​
 +nehmen sie lieber sprechende Namen wie ''​grundpreis''​ und ''​arbeitspreis'', ​
 +die sind nicht zu verwechseln. Sonst bleibt der Sinn dunkel.
 +
 +==== Verben und Substantive ====
 +
 +Verben bezeichnen Tätigkeiten,​ Substantive einen Zustand oder ein Ding.
 +<code cpp>
 +bool lesen = false;
 +gucken(Sie, Film);
 +</​code>​
 +
 +**Pro:** Offensichtlich. Das erschließt sogar den Hintersinn. ​
 +(Manchmal sind C++-Quellen sogar witzig.)
 +
 +**Kontra:** Lassen Sie sich nicht irre machen. Lesen bildet. ​
 +Dabei erfahren sie sogar, ​
 +das Verben substantivisch und Substantive als Verlaufsform (Prozess des Lesens) ​
 +gebraucht werden können.
 +
 +==== Prädikate ====
 +
 +Funktionen, die Wahrheitswerte liefern, ​
 +werden in der mathematischen Logik als Prädikate bezeichnet. ​
 +Durch Vorsilben wird ihre Rolle deutlich.
 +
 +<code cpp>
 +if (isdigit(cin.peek())) std::cin >> obergrenze;
 +if (istPrimzahl(n)) std::cout << n << ' ';
 +std::cout << athene.hateinenVogel();​
 +</​code>​
 +
 +**Pro:** Machen Sie durch Vorsilbe den Charakter des Funktionsaufrufs als Entscheidungsfrage deutlich.
 +
 +**Kontra:** Das kollidiert mit dem ''​get...()''​-Schema für Methoden: ​
 +''​isget...()''​ oder ''​getis...()''?​ Siehe unten. ​
 +Vertrauen Sie nicht darauf, dass solche Funktionen Wahrheitswerte liefern: ​
 +''​isdigit()''​ liefert ''​int''​ und Athene könnte ''​hateinenVogel()'' ​
 +auch als Befehl auffassen, sich ein Vogelbauer zu kaufen. ​
 +Vorsilben sind ein Hinweis, aber keine Garantie, was eine Funktion tut.
 +
 +==== Ergebnistyp ====
 +
 +Funktionsnamen können ihren Ergebnistyp codieren.
 +
 +<code cpp>
 +while (fabs(x-y) > epsilon) { /* berechne genaueres x und y */ }
 +long betrag = labs(m,n);
 +</​code>​
 +
 +**Pro:** Ein Kodierungsschema vorausgesetzt,​ weiß man immer, was die Funktionen liefern.
 +
 +**Kontra:** Das funktioniert nur, wenn die Anzahl der Typen begrenzt ist wie in C. 
 +Wie wäre die Vielfalt der Klassen eines objektorientierten System unterzubringen? ​
 +In C lassen sich keine gleichnamigen Funktionen mit unterschiedlichen Argumentlisten bauen (überladen). ​
 +Deshalb griff man zum Typvorspann,​ um z.B. den Betrag für Ganzzahlen, ​
 +long- und double-Werte definieren zu können. ​
 +Bei Schablonen (Templates) in C++ will man ja gerade typunabhängig programmieren: ​
 +''​z = max(x,​y);'' ​
 +Ahnliches geht auch mit Präprozessormakros,​ nur dann ohne Typprüfung.
 +
 +==== Ungarische Notation ====
 +
 +Alle Namen, sowohl Variablen als auch Funktionen, werden mit Typ-Präfixen versehen.
 +
 +<code cpp>
 +char* lpszName = "​Charles Simonyi";​
 +int iGanzzahl;
 + 
 +IsActive = 
 +(GetWindowLong(GetDlgItem(HWindow,​ nID), GWL_STYLE) & WS_DISABLED)
 +                                                   == WS_DISABLED;​
 +</​code>​
 +**Pro:** Jederzeit voller Durchblick über den Typ von Variablen. ​
 +Außerdem verwendet das erfolgreichste Software-Unternehmen der Welt diesen Stil.
 +
 +**Kontra:** Voller Durchblick? ​
 +Hunderte Funktionen, die Dutzende Parameter brauchen, bilden die Windows-API. ​
 +Wer da vollen Durchblick behält, hat seinen Kopf für nichts anderes mehr frei. 
 +Bei objektorientiertem Ansatz hätte hier vielleicht ''​dialog->​is_active()''​ genügt. ​
 +Typpräfixe behindern die Kapselung und Abstraktion vom konkreten Datentyp ​
 +und erschweren die Änderung der Implementation. ​
 +Lesen Sie dazu den Artikel über {{ungarn|ungarische Notation]] in dieser Rubrik.
 +
 +==== Schwäbische Notation ====
 +
 +Schwaben sind sparsam, auch mit Kürzeln. Eigentlich haben nur Zeiger eine Kennung.
 +<code cpp>
 +float a=3, b=4, c=5;     // bekannte Werte
 +float x, y, z;           // unbekannte Groessen, siehe [Polya]
 +int i, j, k, l, m, n;    // gute alte FORTRAN-Konventionen
 +int *p, *q;              // baumelnde Zeiger
 +char* pName = "​Schwabe";​ // p = pointer
 +char *s, *str;           // Zeichenketten
 +</​code>​
 +
 +**Pro:** Viele lokale Variablen werden "​schwäbisch"​ knapp benannt. ​
 +Zum Teil wirken hier mathematische Traditionen oder die Erfahrungen mit älteren Programmiersprachen.
 +
 +**Kontra:** Kurze Namen sorgen nicht für Verständlichkeit. ​
 +Sie erfordern dann zusätzliche Kommentare. ​
 +Stimmen dann Kommentar und Quelltext nicht mehr überein, ​
 +sind vermutlich beide falsch. Nutzen Sie beschreibende Namen.
 +
 +==== Groß oder klein ====
 +
 +Nutzen Sie die Großschreibung als "​drittes Signalsystem"​. ​
 +Auch hier haben sich Traditionen eingeschliffen. ​
 +Variablen, Funktionen und Methoden beginnen zumindest klein, ​
 +eigene Typnamen groß, Konstanten werden komplett aus Großbuchstaben gebildet.
 +
 +<code cpp>
 +#define MAX 50
 +enum Wochentag {DI, MI, DO}; // fuer Di-Mi-Do-Professoren
 +int maxi = max(x,y);
 +class Max;
 +</​code>​
 +
 +**Pro:** Es ist von Nutzen zu wissen, welche Rolle eine Bezeichnung spielt. ​
 +"Warum das so ist? Ich will es euch sagen: ich weiß es nicht! Das ist eben Tradition." ​
 +sagt Tevje im "​Fiedler auf dem Dach". --- Andere Sprachen, andere Sitten.
 +
 +**Kontra:** Ich pfeife auf Traditionen. C++ ist meine Erstsprache. ​
 +Ich muss nicht nach den "alten Hasen" richten, schon gar nicht ihre Fehler wiederholen.
 +
 +==== get und set ====
 +
 +Methoden, die Werte holen oder setzen, machen dies durch Vorsilben get bzw. set deutlich.
 +
 +<code cpp>
 +meinKonto.setGuthaben(deinKonto.getGuthaben());​ // ich will auch soviel!
 +</​code>​
 +
 +**Pro:** Dies erhöht die Verständlichkeit.
 +
 +**Kontra:** Was ist mit Funktionen, die sowohl Werte abfragen ​
 +als auch schreiben wie ''​berechneZinsen()''? ​
 +Die get/​set-Vorsilben waren in Sprachen nötig, ​
 +die gleichnamige (überladene) Funktionen mit unterschiedlichen Parametern nicht zulassen. ​
 +Compiler für C++, Java, C#, ... interessiert get/set weniger als const 
 +(siehe [[const|extra Kolumne]]).
 +
 +==== Unterschiedliche Parameterzahl ist ausreichend ====
 +
 +Welche Methoden Werte holen oder setzen, ist durch die Parameterzahl ersichtlich.
 +<code cpp>
 +int stellen = std::​cout.precision();​ // "​get"​
 +std::​cout.precision( stellen+2 );    // "​set" ​
 +</​code>​
 +**Pro:** Es ist doch offensichtlich, ​
 +dass eine Methode ohne Argument nur einen Wert holen kann.
 +
 +**Kontra:** Quelltexte müssen ohne Nachdenken (!) lesbar sein. 
 +Die Methode könnte auch Direktzugriff vermitteln.
 +
 +==== Direktzugriff ====
 +
 +Methoden referenzieren den direkten schreibenden oder lesenden Direktzugriff auf den Wert.
 +<code cpp>
 +template <class T> class vector
 +{ public:
 +    const T& at(int index) const { return data[safe(index)];​ }
 +          T& at(int index) ​      { return data[safe(index)];​ }
 +  private: ​  // ...                      mit Bereichsprüfung ​
 +    T* data;
 +};
 +
 +vector<​float>​ v(10, 3.14); ​
 +float wert = v.at(5); ​     // "​get"​
 +v.at(3) = wert+2.718; ​     // "​set"​
 +</​code>​
 +**Pro:** Im UML-Entwurf werden get/​set-Paare zu einem (öffentlichen) Attribut ​
 +meist nicht aufgeführt. Dies übernehmen diese Methoden mit dem Attributnamen. ​
 +Die Attribute sind lesend und schreibend auf dieselbe Weise anzusprechen. ​
 +Bei einem ''​const''​-Vector wird die ''​const''​-Methode benutzt, ​
 +sonst die mit Schreibrechten.
 +
 +**Kontra:** Der interne Datenwert muss dann anders genannt werden ​
 +(Namenskonflikt,​ siehe weiter unten). ​
 +Der Referenz kann jeder Wert zugewiesen werden. ​
 +Dies unterliegt keiner Kontrolle durch den Programmierer.
 +
 +==== C# kann es noch besser ====
 +
 +Attributen werden Lese-/​Schreib-Eigenschaften (properties) zugeordnet.
 +<code cpp>
 +public class Konto { 
 +  public int guthaben {
 +    get { return guthaben; ​ }
 +    set { guthaben = value; } // Prüfung value und Korrektur möglich
 +  }  ​
 +}; 
 +
 +  // ...
 +  konto.guhaben = 1000000;
 +</​code>​
 +**Pro:** Es sieht fast aus wie in UML: {readonly}-Attribute haben keine set-Eigenschaft.
 +
 +**Kontra:** Language wars! Die Sprache kann man nur bei Projektbeginn wählen.
 +
 +==== Attributnamen wie im Entwurf ====
 +
 +Bei Attributnamen,​ Konstruktorparametern und Methoden ​
 +muss der Namenskonflikt bewusst aufgelöst werden, um Konfusion zu verhindern.
 +<code cpp>
 +class Datum
 +{
 +public:
 +  Datum(int jahr, int monat, int tag);
 +  int  getJahr() const        { return jahr; }
 +  void setJahr(int neuesJahr) { jahr = neuesJahr; }
 +  // ...
 +private:  ​
 +  int jahr, monat,tag;
 +};
 +
 +Datum::​Datum(int j, int m, int t)
 +  : jahr(j), monat(m), tag(t)
 +{
 +}
 +</​code>​
 +**Pro:** Gleichnamige Funktionen und Attribute sind nicht möglich. ​
 +Funktionsparameter ''​jahr''​ und Attribute ''​this->​jahr'' ​
 +können nicht in der Initialisiererliste unterschieden werden.
 +
 +**Kontra:** Der Konstruktorrumpf kann nicht in die Klasse inline eingebettet werden, ​
 +ohne seine sprechende Parameterliste zu verlieren, ​
 +die gut für automatische Dokumentation (Doxygen) nutzbar wäre.
 +
 +==== Private Attributnamen umbenennen ====
 +
 +Verborgene Attributnamen werden markiert durch Unterstriche oder Vorsilben.
 +<code cpp>
 +class Datum
 +{
 +public:
 +  Datum(int jahr, int monat, int tag);
 +    : jahr_(jahr),​ monat_(monat),​ tag_(tag)
 +  {
 +  }
 +  int  jahr() const        { return jahr_; }
 +  void jahr(int neuesJahr) { jahr_ = neuesJahr; }
 + 
 +private:  ​
 +  int jahr_, monat_, tag_;
 +};
 +</​code>​
 +
 +**Pro:** Unterstriche "​verbergen"​ den Attributnamen ​
 +und machen den Implementationscharakter deutlich. ​
 +Auch beim internen Zugriff innerhalb von Methoden der Klasse ​
 +stellt der Unterstrich ein Warnsignal dar: Wäre es möglich oder gar besser, ​
 +den Zugriff über eine (öffentliche) Methode zu erreichen? ​
 +Den Overhead muss man nicht fürchten, wenn die Methoden inline implementiert sind. 
 +Aber es spart Ärger und Arbeit, wenn sich die Daten-Implementation ändern muss.
 +
 +**Kontra:** Womit wir wieder bei [[ungarn|Ungarischer]] ​
 +und ähnlicher Notation angekommen wären: ​
 +''​mnJahr''​. Das ''​m''​ steht für member data, das ''​n''​ für natürliche Zahl. 
 +Weitere Varianten sind ''​seinJahr'',​ ''​dasJahr'',​ ''​itsYear''​. ​
 +Ganz und gar abzuraten ist von Denglisch: jahr / year. 
 +Da ist überhaupt nicht mehr klar, 
 +welche Sprache innerhalb und ausserhalb der Klasse verwendet wird, 
 +zumal in Klassen auch äußere Schnittstellen anderer Klassen verwendet werden.
 +
 +===== Qual der Wahl =====
 +
 +Ihre Abstimmung:
 +^ Entscheidung ^ Ja ^ Unentschieden ^ Nein ^
 +|möglichst kurze Namen | _ | _ | _ |
 +|keine Abkürzungen | _ | _ | _ |
 +|keine Unterstriche an Namen | _ | _ | _ |
 +|Unterstriche in langen Namen | _ | _ | _ |
 +|Müssen Namen "​sprechen"?​ | _ | _ | _ |
 +|Wortarten beachten | _ | _ | _ |
 +|Vorsilben für Prädikate | _ | _ | _ |
 +|Ergebnistyp im Funktionsnamen erkenntlich | _ | _ | _ |
 +|Ungarische Notation verwenden | _ | _ | _ |
 +|Schwäbische Notation verwenden | _ | _ | _ |
 +|Groß-/​klein-Schreibung nutzen | _ | _ | _ |
 +|get/​set-Methoden | _ | _ | _ |
 +|gleiche Funktionsnamen,​ andere Parameterzahl | _ | _ | _ |
 +|Direktzugriffsmethoden auf Attribute | _ | _ | _ |
 +|Zu C# wechseln? | _ | _ | _ |
 +|Attributnamen wie in Entwurf | _ | _ | _ |
 +|Kennung für Attribute | _ | _ | _ |
 +
 +Ohne Konventionen ist man frei. Freiheit macht Angst. ​
 +Freiheit kann (auch andere) das Fürchten lehren. ​
 +Amokläufer scheren sich nicht um Konventionen. ​
 +Revolutionäre und Revoluzzer((Krachmacher, ​
 +die sich ihres Vorteils wegen für Umwälzer ausgeben und sich wie Dampfwalzen verhalten.))
 +stellen Konventionen in Frage. Freiheit ist kein Kantischer Wert an sich. 
 +Freiheit ist nicht Freiheit von allem, vor allem nicht Freiheit von Verantwortung. ​
 +Die Freiheit des Einzelnen endet an der Freiheit der anderen [Robespierre]. ​
 +Freiheit ist auch die Freiheit der Andersdenkenden [Luxemburg]. ​
 +Freiheit heißt nicht, alles tun zu können, sondern nicht tun zu müssen, ​
 +was man nicht will [Rousseau]. Freiheit heisst auch, sich entscheiden zu müssen. ​
 +Tue ich das nicht selbst, oder kann ich es nicht, dann tun es andere, für oder gegen mich.
 +
 +===== Quellen =====
 +
 +  * [Polya] G. Polya: How to solve it. 2nd edn. Princeton Univ. Press (1945, 1985) 134-141, 208.
 +
 +Dies war ein "​Brain-Dump"​. Es sind leider zu viele Quellen. ​
 +Möglicherweise ist auch dieser Text (nur) ein Beitrag zur Umweltverschmutzung. ...
 +
 +Weiterführende Literatur:
 +
 +  * [Stroustrup] http://​www.research.att.com/​~bs/​C++.html ​
 +  * [Google] ​    ​http://​google.de/​search?​q=C%2B%2B+coding+style
 +
  
lernen/naming.txt · Zuletzt geändert: 2014-07-13 16:15 (Externe Bearbeitung)