Dokumentation durch Namenskonvention

MarvinF

Newbie
Registriert
Sep. 2022
Beiträge
2
Hallo Community,

ich suche nach einer üblichen Bezeichnung für den Vorgang der "Dokumentation durch Namenskonvention". Wenn ich z. B. eine Methode getX() nenne, kann man als Verwender dieser Methode erwarten, dass der Wert x direkt aus dem Speicher geholt und returniert wird. So könnte die Methode etwa wie folgt implementiert sein.

public int getX()
{
return x;
}

Nicht zu erwarten ist aber, dass erst in irgendwelchen komplizierten Speicherstrukturen nachgesehen wird oder in einer DB etc., also dass die Ermittlung von x teuer ist. In diesem Fall verwende ich gerne findX().

Auf diese Weise dokumentiert sich die API ein Stück weit von ganz alleine nur durch die Einhaltung der Namenskonvention.

Nun gibt es doch sicher in der Informatik einen schönen knackigen Begriff, der mir in meinem langen Studium durch die Lappen gegangen ist. Kennt den jemand?

Vielen Dank und viele Grüße
Marvin
 
Habe zwar kein Informatik studiert, aber dass man Code durch Verwendung "intelligent" gewählter Variablen- und Funktionsnamen deutlich lesbarer macht, ist eine Binsenweisheit :)
Dass es dafür anscheinend einen Fachbegriff gibt, wusste ich nicht mal. :confused_alt:

Um eine zusätzliche Dokumentation kommt man meiner Erfahrung nach idR trotzdem nicht drumrum.
 
Demon_666 schrieb:
Habe zwar kein Informatik studiert, aber dass man Code durch Verwendung "intelligent" gewählter Variablen- und Funktionsnamen deutlich lesbarer macht, ist eine Binsenweisheit :)
Nö. Sprechende Namen sind das A und O. Die Frage ist nur wie weit man das treibt.

Eine adäquate Dokumentation ersetzen sprechende Namen natürlich trotzdem nicht. Statt eine Methode "GetSomeImportantVariableFromSQLDatabase" zu nennen, kann man sie auch einfach "GetVariable" nennen und die Methode dafür mit einem /// Blick zu versehen, in dem man mittels <summary> bzw. <param> Tag (und weiteren) Hilfetexte hinterlegt, die von IntelliSense bei der Verwendung der Methode angezeigt werden und sogar als Doku exportiert werden können. Trotzdem sollte die Methode an sich natürlich einen halbwegs sprechenden Namen haben damit man sie zB auch bei der Navigation im Quellcode (zB die DropDown-Liste in Visual Studio für die aktuelle Klasse) schneller findet.
 
  • Gefällt mir
Reaktionen: _killy_
Gut benannte Methoden, Variablen, Klassen u.s.w. helfen natürlich beim verstehen von Code. Verständnis zu schaffen ist auch Ziel der dazu anzufertigen Dokumentation. Daher sollte das schon "Hand in Hand" erfolgen. Allerdings glaube ich kaum, das man auf eine separate Dokumentation verzichtet werden kann. Aber dort nur zu nennen das "getX" den wert "X" bestimmt ist nicht Ziel davon. Das geht besser mit "JavaDoc" und vergleichbaren Kommentar-Ergänzungen, die inzwischen in vielen Programmiersprachen nutzbar und auch in den IDEs unterstützend (Tooltips, etc.) sind. Aber auch die alleine wird nicht reichen. Das drumherum (Konfigurationsdateien, wie kann eine Entwicklungsumgebung eingerichtet werden, wie wird die Software verteilt, etc.) sollte auch irgendwo stehen. Aber das ist übergeordnet und gehört daher nicht in die Kommentar-Ergänzungen einer Klasse.
Dazu kommen noch Überschneidungen mit diversen "Pattern" welche man in der Softwareentwicklung nutzt. Die Ratschläge was man tun und lassen sollte (Anit-Pattern) kann lähmend sein und man kann ganz viel dazu lesen. Erfahrung haben, anlesen oder erfragen ist da das beste was man da machen kann.

Allgemein könnt man darüber nachdenken. "getX" als Interface zu definieren und die Implementierung (kommt aus einer DB; von einem anderen System via API; ist immer gleich für einen Test) weitgehend offen zu lassen.
Mit Kommentar-Ergänzungen (einfach mal nach "JavaDoc für [deine Programmiersprache]" suchen) an Interface beschreiben was Ziel von dem Interface und von "getX" ist. In der separaten Dokumentation auf das aus den Kommentar-Ergänzungen generierte Dokumentationsdokument ggf. verweisen. Und die eigentliche Implementierung via Dependency-Injection-Framework dann "zusammenstecken" (Konfigurieren) lassen.

Durch die Verwendung von "Dependency-Injection" kann dann z.B. für einen Test eine andere Implementierung genutzt werden, da ja sonnst auch z.B. eine DB laufen, konfiguriert und mit Daten bestückt sein müsste. Aufwand der schnell sehr lästig wird und daher einen noch mehr dazu verleitet keine Tests zu machen. Was aber ganz schlecht ist.

Sich darüber in klaren zu sein und die Disziplin zu haben das auch (entgegen der "schnell und schmutzig"-Tendenzen durch Vorgesetzte, Zeit, Geld) durchzuziehen macht den unterschied zwischen guter und schlechter Software (und -Entwicklern).
 
  • Gefällt mir
Reaktionen: _killy_ und Raijin
Da bin ich voll bei dir. Der Kommentar von @Demon_666 liest sich allerdings so als wenn sprechende Namen hinfällig sind und das ist eben nicht der Fall. Sprechende Namen ersetzen keine adäquate Dokumentation, aber sie erhöhen in jedem Fall die Lesbarkeit des Codes. Vernünftige Namen und Dokumentation gehen stets Hand in Hand.
 
  • Gefällt mir
Reaktionen: mental.dIseASe und FlaTLin3
Ich könnte jetzt wunderbar in diese Diskussion einsteigen. Ein herrliches, aber leider anderes Thema.

Lasst uns doch bitte dazu zurückfinden, ob es einen kurzen, knackigen Begriff gibt für die "Dokumentation durch Namenskonvention". Wenn es ihn gibt, fein. Dann wüsste ich ihn gerne. Wenn es ihn nicht gibt, ok, muss ich mir halt selber etwas ausdenken (und vielleicht für die zukünftige Literatur prägen. ;-) ).
 
  • Gefällt mir
Reaktionen: FlaTLin3
Raijin schrieb:
Da bin ich voll bei dir. Der Kommentar von @Demon_666 liest sich allerdings so als wenn sprechende Namen hinfällig sind und das ist eben nicht der Fall. Sprechende Namen ersetzen keine adäquate Dokumentation, aber sie erhöhen in jedem Fall die Lesbarkeit des Codes. Vernünftige Namen und Dokumentation gehen stets Hand in Hand.
Da wurde aber nicht genau gelesen ;)

Binsenweisheit (wikipedia):
"Als Binsenweisheit oder Binsenwahrheit wird ein Gemeinplatz oder eine allgemein bekannte Information bezeichnet, besonders, wenn zum Ausdruck gebracht werden soll, dass eine als interessant vorgetragene Erkenntnis keinen besonderen materiellen Wert hat, keine Neuigkeit darstellt oder keinen Wissenszuwachs bringt."

Oder Kurzform: Je lesbarer durch entsprechende Wahl der Namen, desto verständlicher (was ja eben logisch und klar ist).
 
  • Gefällt mir
Reaktionen: Raijin
In der Tat, Asche auf mein Haupt. Irgendwie hatte ich das anders gelesen, war wohl abgelenkt ;)
 
  • Gefällt mir
Reaktionen: Demon_666
MarvinF schrieb:
Verwende doch bitte "returned" oder zurückgeben. "returniert" gibts nicht. Retourniert werden Pakete.
MarvinF schrieb:
Lasst uns doch bitte dazu zurückfinden, ob es einen kurzen, knackigen Begriff gibt für die "Dokumentation durch Namenskonvention".
Deine Antwort hast du bereits erhalten. Ein Methodenname oder dessen Präfix ist nur durch Kontext zu erfassen und selbst dort ist es nirgendwo eindeutig, ggf. nicht mal irgendwie ableitbar.

Spätestens beim Einsatz von Dependency Injection ist überhaupt nichts mehr gültig, denn MessageReceiver::getMessages() kann aus einem InMemory Store erfolgen, mit einem Cache dazwischen geschaltet, ggf. ungecached direkt via HTTP Call, ggf. TTL-gecached mit HTTP Call im Hintergrund oder oder oder. Es deklariert nur die Operation "gib mir die Nachrichten". Wie das erfolgt ist eben Sache der dahinter liegenden Implementierung und auch ob dieser Implementierung noch Caches davor geschaltet werden oder ob für die Dev-Umgebung noch zusätzlich ein Tracing aktiviert wird, ggf. ob oben drauf nochmal ein Logging stattfindet oder oder oder.

Dein
Code:
var receiver = new SlackApiMessageReceiver();
wird dann schnell zu einem
Code:
var receiver = new TraceableMessageReceiver(
    new LoggableMessageReceiver(
        new CacheableMessageReceiver(
            new SlackApiMessageReceiver(
                new HttpFactory(),
                new DataStoreFactory()
            )
        )
    )
);
oder per DI dann einfach zu einem
Code:
class MyMessageReceiver : MessageReceiver
{
    public MyMessageReceiver( MessageReceiver MessageReceiver )
    {
        // ...
    }
}
Wie dann etwas geschieht liegt nicht mehr in deiner Hand. Ggf. sind noch einige Decorator oder Adapter dazwischen... :O

Die Methode getMessages() heißt also nur "gib mir die Nachrichten" und nicht wie das passiert, denn das ist Sache der konkreten Implementierung.

PS: Deine Begrifflichkeit grenzt schon fast an Blasphemie. Dokumentiert wird da nämlich gar nichts, höchstens der Use Case.
 
Yuuri schrieb:
Die Methode getMessages() heißt also nur "gib mir die Nachrichten" und nicht wie das passiert, denn das ist Sache der konkreten Implementierung.
Das hab ich mir beim Lesen auch schon gedacht, wenn ich den Namen der Funktion zu Dokumentationszwecken immer ändern müsste wenn sich der Inhalt einer Funktion ändert wäre der purpose einer Funktion an sich ja defeated...
 
floq0r schrieb:
wenn ich den Namen der Funktion zu Dokumentationszwecken immer ändern müsste wenn sich der Inhalt einer Funktion ändert wäre der purpose einer Funktion an sich ja defeated...
Manchmal ist das "wie" (oder ein Teil davon) auch Teil des Zwecks der Funktion.
Das ist kontextabhängig.
 
Es gibt ein Paradigma "convention over configuration", vielleicht meintest du das... dieses hat aber mit Dokumentation recht wenig zu tun, sondern beschreibt lediglich eine Vorgehensweise, bei der man sich, statt sich mit viel Konfigurationsaufwand Programmabläufe zusammen zu stellen, einfach an vereinbarte Code-Konventionen hält.

Die Verwendung des Paradigmas kann eine Dokumentation durchaus erleichtern, jedoch vermute ich bei dir mal einen Hintergedanken deiner ursprünglichen Frage: Du möchtest die Dokumentation

  • Automatisch aus dem Code erstellen lassen
  • so vollständig wie möglich halten und nichts vergessen
  • so wartungsarm wie möglich gestalten

Dazu gibt es verschiedene Ansätze, allerdings gehört meiner Ansicht nach zu einer GUTEN Dokumentation immer auch etwas beschreibender Text. Bei mir hat sich in der Vergangenheit immer folgendes bewährt:

  • Verwende statt "konventionsbasierter Methodennamen" lieber JavaDoc und Annotations, das ist flexibel, lässt sich aber auch automatisiert auslesen und ist auch im Code
  • Ergänze diese Annotationen durch optionaleBeispiel-Dateipakete in einer passenden Verzeichnisstruktur, in denen jeweils optional ein bisschen Beschreibener Text und ein bisschen Beispielcode hinterlegt werden können
    • MyClass.getX.sample.java => Beispielcode
    • MyClass.getX.sample.md => Beschreibener Text im Markdown-Format
  • Schreibe anschließend für deine automatisch generierte HTML-Dokumentation ein Stückchen einfachsten JavaScript Code, dass in der Lage ist, die Samples auf Klick nachzuladen
Das ist ein Kompromiss aus Wartungsaufwand und Qualität... Schöner wäre ein sauber geschriebener Text mit passenden auf einander aufbauenden Beispielen - das mag bei sich kaum verändernden APIs noch möglich sein, aber bei größeren Projekten die sich schnell bewegen kann das super aufwändig werden.

Schau dir mal https://swagger.io/ (swagger /openAPI) an, da kann man sogar automagisch einen Rest-Client generieren lassen, mit dem man die API Aufrufe testen kann, während die Dokumentation über Code-Kommentare auch eingeblendet wird. Sehr leistungsfähig.
 
  • Gefällt mir
Reaktionen: Piktogramm
Ich denke, der Begriff den du suchst ist "Intention-Revealing Naming" oder "Intention-Revealing Names".

Dazu schreibt Robert C. Martin in seinem Buch Clean Code auf Seite 18:
The name of a variable, function, or class, should answer all the big questions. It should tell you why it exists, what it does, and how it is used. If a name requires a comment, then the name does not reveal its intent.

Zu deinem Beispiel möchte ich noch etwas anmerken:

Zu bedenken ist, dass in der Regel objektorientiert programmiert wird. Das bedeutet, dass der Kontext durch eine Klasse bestimmt wird. So unterscheidet Domain-Driven-Design zwischen dem Datenmodell, welches durch Entities und ValueObjects beschrieben wird und Repositories, welche die Persistenzschicht abstrahieren. In einer Klasse XRepository kann man von einer getX-Methode erwarten, dass diese z.B. auf eine Datenbank zugreift, während dies bei einer getX-Methode aus einer Klasse des Datenmodells nicht zu erwarten ist.

Genauso gut kann - für den Fall, dass X nicht existiert - bei getX(key) auch eine Exception geworfen werden, während findX(key) in dem Fall null zurück liefert. Die Intention dahinter ist, dass bei getX X existieren muss, während bei findX die Nichtexistenz von X als mögliches Ergebnis erwartet werden kann.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: mental.dIseASe und Piktogramm
MarvinF schrieb:
Nicht zu erwarten ist aber, dass erst in irgendwelchen komplizierten Speicherstrukturen nachgesehen wird oder in einer DB etc., also dass die Ermittlung von x teuer ist. In diesem Fall verwende ich gerne findX().
Das Grundsätzliche wurde hier bereits besser ausgedrückt als ich es könnte, ich hätte bei der Namensgebung jedoch einen Einwand.

Um Ressourcen/Daten extern zu erlangen würde ich das Verb "fetch" verwenden. Bei "find" würde ich Patternmatching auf Ressourcen (meist Dateien) erwarten, aber nicht deren Inhalt. Für dies wäre dann "grep" da.

Zugegeben bin ich da biased und durch *nix verseucht, aber in diesem Kontext wäre es konsequent:
https://www.unix.com/man-page/FreeBSD/1/FETCH/
https://www.unix.com/man-page/FreeBSD/1/FIND/
https://www.unix.com/man-page/FreeBSD/1/GREP/

Was ich jedoch nicht machen würde, wäre Bezeichnungen anhand von erwarteten Konsequenzen für die Laufzeit zu wählen! Du kannst während der Entwicklung kaum absehen wie sich das Ganze zukünftig entwickeln wird. Gerade bei Objektorientierung wäre ich gar dafür bei get/set zu bleiben und die Namen der Klassen und deren Methoden entsprechend eindeutig zu wählen.
 
Zurück
Oben