Beispiel gefällig?

In der IT-Welt gibt es zahlreiche Fälle, in denen Platzhalterwerte für Dokumentationen, Tests und Simulationen benötigt werden. Diese Werte sollen realistisch erscheinen, dürfen aber nicht zu echten, existierenden Daten führen.

Auch über die IT-Welt hinaus werden solche Werte hier und da verwendet, sei es in Film und Fernsehen, in Spielen oder anderen Medien.

Natürlich können sich solche Beispielwerte einfach ausgedacht werden. Bei zugeteilten Ressourcen, wie Domains, Telefonnummern oder IP-Adressen kann dies allerdings zu Problemen führen.

Der Missbrauch echter Domains oder IP-Adressen kann dort zu technischen Problemen, Datenschutzverletzungen oder rechtlichen Konsequenzen führen.

In diesem Artikel werden die Hintergründe, die technischen Standards und die Best Practices im Umgang mit solchen Ressourcen, wie Beispieldomains, IP-Adressen und anderen reservierten Werten behandelt.

Nutzung

Im ersten Moment stellt sich vielleicht die Frage, wo solche Beispieldaten bzw. Ressourcen benötigt werden.

In Dokumentationen und Handbüchern oder auch Anleitungen für unterschiedlichste Netzwerkgeräte oder Software werde Dinge wie IP-Adressen oder URLs gezeigt. Wünschenswert ist es, bei solchen Beispielen keine echten Ressourcen zu involvieren.

In der Softwareentwicklung und beim Testen von Anwendungen setzen Entwickler gezielt Beispiel-Adressen ein. Diese Praxis dient dazu, sicherzustellen, dass Quellcode-Beispiele und Testumgebungen niemals versehentlich mit Produktivressourcen interagieren. So kommen in Unit-Tests oder Konfigurationsdateien oft Dummy-Domains wie example.org oder test.example zum Einsatz.

Auch IP-Adressen werden bewusst gewählt, um reale Systeme nicht zu beeinflussen.

Das Gleiche gilt für Telefonnummern, wer hier auf einer Visitenkartenvorlage eine Nummer zeigt, möchte sicherstellen, dass diese nicht genutzt wird oder Unbeteiligte belästigt werden.

In Produktdemos oder Marketingmaterial befinden sich oft Platzhalter. Etwa Screenshots einer CRM-Software zeigen Max Mustermann – +1 555 0176 als Kontakt, um realistische Daten vorzuführen, ohne echte Personen und Nummern preiszugeben.

Oder ein Cloud-Anbieter demonstriert eine Konsole mit einem fiktiven Server server.example.com und der IP 203.0.113.42, um die Oberfläche exemplarisch darzustellen.

In der Systemadministration werden separate Testumgebungen mit Dummy-Daten betrieben. Beispielsweise könnte ein E-Mail-System auf einer internen Domain test.example laufen, damit Test-E-Mails nicht in die Außenwelt gelangen. Datenbanken in Staging-Systemen enthalten Telefonnummern aus einem Pool von Beispielnummern, damit keine versehentlichen SMS oder Anrufe an echte Kunden herausgehen.

In all diesen Fällen dienen die Beispielwerte dazu, realitätsnahe Situationen nachzustellen, ohne reale Adressen, Telefonnummern oder weitere zugeteilten Ressourcen zu benutzen. Dadurch können Lernende, Entwickler oder Nutzer gefahrlos experimentieren und die Beispiele nachvollziehen, ohne unbeabsichtigte Seiteneffekte in der realen Welt.

Unberechtigte Nutzung reservierter Ressourcen

Oft jedoch werden solche reservierten Ressourcen verwendet, ohne auf deren Verfügbarkeit zu achten. Ein Beispiel für eine solche Nutzung ist die E-Mail-Adresse , welche insbesondere vor einigen Jahren gerne und häufig als Absender-Adresse für Newsletter oder Support-E-Mails verwendet wurde.

Mit dem notwendigen Kleingeld kann auch als E-Mail-Adresse genutzt werden

Derjenige der die Kontrolle über die Domain noreply.com ausübt, kann diese dazu nutzen, E-Mails, welche auf solchen E-Mail-Adressen auflaufen zu empfangen und damit potenziell missbräuchlich nutzen.

Eine fiktive und doch reale Domain aus dem Spiel „Do Not Feed the Monkeys“

Auch in anderen Medien, wie Spielen, sind immer wieder Domains zu finden, welche im besten Fall dem Spieleproduzenten gehören, im schlimmsten Fall aber andere Eigentümer haben.

Die Domain steht zum Verkauf

Was auf den ersten Blick harmlos erscheint, kann zu Problemen und ernsthaften Konsequenzen führen.

Risiken und Nebenwirkungen

Zu den Risiken und Nebenwirkungen der Verwendung solcher Ressourcen, welche nicht im Eigentum liegen, oder für den Beispielgebrauch vorgesehen sind, zählen unter anderem juristische Konsequenzen. Die unberechtigte Nutzung einer existierenden Telefonnummer oder IP-Adresse oder Domain kann zu rechtlichen Problemen führen.

Leser oder Anwender können der Versuchung erliegen, eine beispielhafte Telefonnummer anzurufen oder eine Kreditkarten-Testnummer als reale Nummer zu verwenden.

Das geschieht öfter als gemeinhin angenommen, z. B. mit amerikanischen Sozialversicherungsnummern. 1938 verwendete ein Geldbörsenhersteller, die E. H. Ferree Company, für Werbezwecke die echte Social Security Number der Sekretärin des Vizepräsidenten, Hilda Schrader Whitcher, auf einer Musterkarte, die in jede verkaufte Brieftasche eingelegt wurde. Trotz Aufdrucken wie Specimen und rotem Druck hielten viele Käufer die Karte für echt und übernahmen die Nummer als ihre eigene.

Zum Höhepunkt im Jahr 1943 nutzten über 5.700 Menschen diese Nummer. Insgesamt haben sie über 40.000 Menschen genutzt. Selbst 1977 benutzten noch zwölf Personen diese Sozialversicherungsnummer. Die Social Security Administration musste die Nummer für ungültig erklären und breit kommunizieren, dass sie nicht verwendet werden darf. Whitcher selbst wurde wegen des Vorfalls sogar vom FBI befragt, empfand den ganzen Trubel aber eher als Ärgernis.

Neben diesem Vorfall gab es immer wieder ähnliche Vorfälle auch mit anderen gefälschten oder illustrativen Sozialversicherungsnummern — unter anderem veröffentlichte das Social Security Board selbst 1940 ein Heft mit einer Fantasienummer (219-09-9999), die später ebenfalls von echten Personen beansprucht wurde.

In der IT verhindern reservierte Adressen, dass Testsoftware Schaden anrichtet. Ohne Beispieladressen könnte es passieren, dass ein Entwickler, natürlich nur zum Test, hart kodierte IP-Adressen oder Domains einbaut, die zufällig jemandem gehören. Im schlimmsten Fall sendet eine solche Software dann Daten an Unbefugte oder beeinträchtigt fremde Systeme.

Mit Beispiel-IPs wie 192.0.2.42 sind solche Kollisionen absichtlich ausgeschlossen. Auch werden potenzielle Konflikte mit künftigen echten Zuweisungen vermieden – ein wichtiger Grund, der auch in der RFC 2606 genannt wird. Niemand muss befürchten, dass etwa die Domain example.com nächstes Jahr von einer Firma registriert oder gekauft wird und plötzlich von bestehender Nutzung real angesprochen wird. Die Domain ist fest als reserviert vorgesehen und dadurch, besser als gewöhnliche Domains, abgesichert.

Insgesamt sind Risiken vorhanden, die von möglichen Belästigungen Unbeteiligter über potenzielle Datenlecks bis hin zu rechtlichen Fragen reichen.

Daher gilt: Real existierende Telefonnummern, Domains oder IP-Adressen haben in Publikationen und Tests nichts verloren, sofern sie nicht ausdrücklich zur Demonstration ausgewählt und genehmigt wurden und sich idealerweise im Eigentum des Nutzers befinden.

Domains

Wer eine Domain als Beispiel nutzen möchte, sollte im einfachsten Fall darauf achten, dass diese Domain im eigenen Besitz und entsprechende Kontrolle über die Domain vorhanden ist.

Dann wäre es kein Problem, eine E-Mail-Adresse wie zu nutzen. Werden Domains allerdings nur als Beispiel benötigt, so kann sich mit einer Beispiel-Domain wie example.com beholfen werden.

Solche Beispieldomains werden in einer Reihe von RFCs, wie der RFC 2606, definiert.

Die Domain example.com ist als Beispieldomain verfügbar

Dort sind die Domains example.com, example.net und example.org als Beispiel-Domains definiert.

In Dokumentation und Beispielen sollten solche Domains verwendet werden, anstatt auf beliebte echte Domains wie yourdomain.com, noreply.com oder im deutschsprachigen Raum auf beispiel.de zu verweisen.

beispiel.de versteht sich als Beispiel-Domain

Auch wenn sich die Domain beispiel.de als Beispiel-Domain versteht, so trägt sie doch keinen offiziellen Status und sollte deshalb nicht als Beispiel für eine solche in Betracht gezogen werden.

Beispiel.de steht ebenfalls zum Verkauf

So steht die Domain mittlerweile zum Verkauf und kann in Zukunft eine andere Nutzung erfahren, die mit dem Beispielzweck nicht übereinstimmt.

Vor allem in TV und Film wurden in der Vergangenheit auch gerne Domains mit ungültigen Top-Level-Domains wie z. B. der .web-Domain verwendet. So tauchte im James-Bond-Film Skyfall die Webadresse www.868000.web auf, während im Film Next Day Air die Domain www.nda.web auftauchte.

Das wird spätestens zu einem Problem, wenn die Top-Level-Domain .web in Zukunft eventuell angeboten wird. Ein vergleichbarer Fall ereignete sich 2024 bei AVM mit der Domain fritz.box.

Neben diesen konkreten Domains sind spezielle Top-Level-Domains für Beispiele reserviert. Diese sind in der RFC 2606 definiert worden. Hierzu gehören die Endungen .test, .example, .invalid und .localhost.

Die Top-Level-Domain .test wird für Tests von aktuellem oder neuem DNS-bezogenem Code empfohlen, während .example bevorzugt in Dokumentationen oder als Beispiel verwendet werden sollte.

Die Top-Level-Domain .invalid ist für solche Domains vorgesehen, die als sicher ungültig erkannt werden sollen.

Zudem wurde die TLD .localhost traditionell in DNS-Implementierungen statisch definiert, um einen A-Record auf die Loopback-IP-Adresse zu verweisen. Sie ist ausschließlich für diesen Zweck reserviert, da jede andere Nutzung mit weitverbreitetem Code in Konflikt geraten würde, der von dieser spezifischen Verwendung ausgeht.

IP-Adressen

Auch bei IP-Adressen kann die Nutzung falscher Beispiele zu Problemen führen. In Film und Fernsehen sind manchmal interessante Kombinationen wie 138.168.212.473 zu sehen, bei welcher es sich um eine ungültige IP-Adresse handelt.

Auch die Nutzung bekannter IP-Adressen, wie der 8.8.8.8 des Google Public DNS-Services, sollte nicht als Beispiel-IP-Adresse eingesetzt werden.

Besser und sicherer ist es hier dafür speziell vorgesehene Bereiche für Dokumentationszwecke zu nutzen. Definiert werden diese für IPv4-Adressen in der RFC 5737. Dabei sind mehrere Bereiche vorgesehen:

192.0.2.0/24
198.51.100.0/24
203.0.113.0/24

Die Blöcke tragen hierbei die Namen TEST-NET-1 (192.0.2.0/24), TEST-NET-2 (198.51.100.0/24) und TEST-NET-3 (203.0.113.0/24).

Gemäß der RFC sollen diese Blöcke von Adressen nicht im Internet auftauchen und in Netzwerken sollten diese Adressblöcke in die Liste der nicht routingfähigen Adressräume aufgenommen werden.

Damit gehören diese Adressbereiche nicht zu realen Netzwerken und können sicher in Handbüchern, Dokumentationen und Beispielen verwendet werden.

Natürlich könnten in der Theorie auch andere Bereiche genutzt werden, wie einer der privaten Adressbereiche wie 192.168.0.0/16. Somit wäre eine IP-Adresse wie 192.168.1.1 auf den ersten Blick unbedenklich. Allerdings werden diese IP-Adressen in internen Netzen produktiv genutzt und fallen damit als Beispiele in vielen Fällen weg.

Für besagte Dokumentationszwecke sind somit die oben genannten TEST-NET-Adressen vorzuziehen, weil sie global eindeutig als Beispieladressen kenntlich sind und nicht mit realen Netzen kollidieren.

Für IPv6 wurde ebenfalls ein Bereich bzw. ein Präfix für Dokumentationszwecke vorgegeben. Definiert ist dieses Präfix in der RFC 3849. Der für Dokumentationszwecke reservierte /32-Bereich lautet: 2001:0DB8::/32.

Jede IPv6-Adresse, die mit 2001:DB8 beginnt, ist somit als fiktiv für Dokumentations- und ähnliche Zwecke ausgewiesen.

Zusätzlich existiert für spezielle Protokoll-Demonstrationen ein reservierter IPv4-Multicast-Adressbereich mit dem Namen MCAST-TEST-NET (233.252.0.0/24), der in RFC 5771 definiert ist. Dieser Bereich ist für Demonstrations- und Beispielzwecke vorgesehen, doch im Alltag sind hauptsächlich die oben genannten Adressbereiche relevant.

Telefonnummern

Eine weitere zugeteilte Ressource sind Telefonnummern. Welche Folgen die unbedachte Verwendung realer Nummern haben kann, zeigt der Song Skandal im Sperrbezirk der Spider Murphy Gang. Dort heißt es im Songtext:

Ja, Rosi hat ein Telefon
Auch ich hab ihre Nummer schon
Unter zwounddreißig sechzehn acht
Herrscht Konjunktur die ganze Nacht

Die dort besungene Telefonnummer 32 16 8 sollte angeblich einer älteren Dame gehören, allerdings erzählte der Sänger Günther Sigl in einem Interview eine andere Geschichte dazu:

Richtig, 32168 war auf einmal die berühmteste Telefonnummer Deutschlands. In München hatten wir die Nummer gecheckt, die gab’s da damals nicht. In anderen Städten aber schon. Einige Jugendliche haben sich da einen Spaß gemacht, angerufen und blöd dahergeredet. Naja, wir haben damals einige Rufnummernänderungen bezahlt und zahlreiche Blumensträuße als Entschuldigung quer durch Deutschland geschickt.

Seit 2006 ist der Rufnummernblock (0)89 32168 000 bis (0)89 32168 999 der Telefónica zugewiesen.

Statt echter Nummern können zu diesem Zweck reservierte Bereiche, sogenannte Drama Numbers, genutzt werden. Im deutschen Raum sind diese über die Amtsblatt-Mitteilung 148/2021 definiert.

In der Amtsblatt-Mitteilung wurden für einige Ortsnetze im Festnetz bestimmte Nummernbereiche zur freien Verwendung definiert:

Berlin: (0)30 23125 000 bis 999
Frankfurt am Main: (0)69 90009 000 bis 999
Hamburg: (0)40 66969 000 bis 999
Köln: (0)221 4710 000 bis 999
München: (0)89 99998 000 bis 999

Wer diese Nummern anruft, wird per Ansage erfahren, dass die Rufnummer nicht erreichbar ist. Interessierte haben die Möglichkeit, dies selbst zu testen, da dies der Zweck der reservierten Nummern ist.

Somit können diese Nummern gefahrlos in Medienproduktionen oder als Beispiel genutzt werden. Neben Festnetznummern sind auch eine Reihe von Mobilfunknummern in den deutschen Netzen freigegeben:

(0)152 28817386
(0)152 28895456
(0)152 54599371
(0)171 39200 00 bis 99
(0)172 9925904
(0)172 9968532
(0)172 9973185
(0)172 9973186
(0)172 9980752
(0)174 9091317
(0)174 9464308
(0)176 040690 00 bis 99

Die Rufnummern des Blockes (0)171 39200 00 bis 99 gehören hierbei der Deutschen Telekom, die des Blockes (0)176 040690 00 bis 99 zu Telefónica, während die restlichen Nummern im Vodafone-Netz liegen.

Internationale Telefonnummern

Ähnlich wie in Deutschland existieren auch international spezielle Rufnummernblöcke für Beispielzwecke. Zu den bekanntesten Nummern zählen sicherlich die Telefonnummern aus dem amerikanischen Raum, die mit der Ziffernfolge 555 beginnen.

In Nordamerika ist seit den 1960er Jahren die Vorwahl 555 für fiktive Nummern gebräuchlich. Telefongesellschaften und Filmstudios einigten sich darauf, diese Vorwahl in Fernsehen und Film zu nutzen.

Tatsächlich sind die nur Nummern 555-0100 bis 555-0199 für rein fiktive Zwecke reserviert – wenn solche Nummern im Film gewählt werden, ist sichergestellt, dass kein tatsächlicher Anschluss existiert. Definiert sind diese Nummern im 555 NXX Line Number Reference Document (ATIS-0300115). Dort heißt es:

With the sunset of the 555 NXX Assignment Guidelines, a block of one hundred (100) 555 line numbers will remain reserved as fictitious, non-working numbers for use by the entertainment and advertising industries. These specific numbers are 555-01XX, i.e., numbers between and including 555-0100 and 555-0199.

In der Kinofassung von Bruce Allmächtig (im Origial: Bruce Almighty), wurde die Nummer von Gott als 776-2323 angegeben. In Buffalo, wo der Film spielte, war die Nummer nicht belegt, aber in vielen anderen Vorwahlbereichen existierte die Nummer. So wurde sie für die DVD, HD-DVD und Bluray-Fassungen schließlich in 555 geändert.

Aktivieren Sie JavaScript um das Video zu sehen.
Video-Link: https://www.youtube.com/watch?v=mbZibNULsxI

Auch in britischen Produktionen kamen häufig Telefonnummern zum Einsatz, die sich nur bedingt als Beispiele eignen. Sehr bekannt ist sicherlich die „neue“ Notrufnummern. Anstatt der 999 soll in der Welt von IT Crowd nur noch die Nummer 0118 999 881 999 119 725 3 gewählt werden.

Aktivieren Sie JavaScript um das Video zu sehen.
Video-Link: https://www.youtube.com/watch?v=HWc3WY3fuZU

Der Sketch spielt auf eine wahre Gegebenheit an: Im Jahr 2003 hatte Großbritannien sein traditionelles Auskunftssystem umgestellt, bei dem früher einfach die 192 gewählt wurde, um eine Telefonnummer zu erfragen. Nach der Liberalisierung mussten Anrufer stattdessen eine der neuen, kommerziellen 118-Nummern wählen, wobei insbesondere die leicht einprägsame 118 118, auch aufgrund einer allgegenwärtigen Werbekampagne, schnell Berühmtheit erlangte.

Zwar existiert der Bereichscode 0118, aber der Rufnummernblock beginnend mit der 999 wird nicht weitergeleitet, sodass zumindest keine Gefahr bestand, hier wirklich jemand zu erreichen.

Allerdings existieren auch in Großbritannien entsprechende Nummern für die Nutzung in fiktivem Kontext. Diese wurde zuletzt 2019, von der britischen Medienaufsicht, dem Office of Communications, veröffentlicht. So könnte das Torchwood-Institut in Cardiff, vielleicht die Telefonnummer 029/20180000 nutzen.

Daneben existieren in vielen anderen Ländern wie Australien, Irland, Südkorea, Schweden oder Frankreich Regelungen und Freigaben für jeweils auf die Länder zugeschnittene Drama Numbers.

Weitere zugeteilte Ressourcen

Neben den genannten Anwendungsfällen, wie Telefonnummern, Domains und IP-Adressen, gibt es weitere Ressourcen, für die gegebenenfalls Beispiele und Testdaten benötigt werden.

Für Kreditkarten wird z. B. von VISA die Testkreditkartennummer 4111 1111 1111 1111 bereitgestellt. Dies ist auch für viele andere Kreditkarten der Fall, hängt aber in der konkreten Ausprägung auch vom jeweiligen Zahlungsdienstleister ab. Gültig sind diese Nummern, dann meist nur in den jeweiligen Testsystemen der Dienstleister.

Auch für Kontonummern, wie IBANs existieren entsprechende Testnummern, welche genutzt werden können.

Best Practices

In der Praxis ist es ratsam, Beispiele klar als solche zu kennzeichnen, um Missverständnisse zu vermeiden. Dies kann durch Kommentare im Quellcode, Fußnoten in Dokumentationen oder spezielle Formatierungen geschehen.

Dokumentationen sollten klar kennzeichnen, dass verwendete Werte nur Beispiele sind. In Software sollte sichergestellt werden, dass Testwerte nicht versehentlich in Produktionsumgebungen gelangen.

Wenn die existierenden Beispieldaten nicht ausreichen, kann in bestimmten Fällen nachgeholfen werden – beispielsweise durch die Nutzung von Subdomains:

api.example.com
blog.example.com
shop.example.com

So bleibt die Beispielhaftigkeit gewahrt. Auch bieten die Beispiel-Top-Level-Domains die Möglichkeit viele Testdaten zu generieren z. B. shop.example, system.example.

Softwareentwickler sollten Mechanismen implementieren, die verhindern, dass echte Daten versehentlich in Testumgebungen verwendet werden. Skripte und Produktionscode können etwa prüfen, ob eine verwendete IP-Adresse oder Domain tatsächlich für Tests vorgesehen ist.

Auch der umgekehrte Fall gilt. In Produktivsystemen können auch Prüfungen eingebaut werden, ob in Feldern wie Telefonnummern oder Domains nur Beispielwerte eingegeben und diesen dann abgelehnt werden.

Daneben sollte man darauf verzichten, für Beispiele Templates aus echten Daten zu erstellen. Es mag verlockend sein, z. B. einen echten Konfigurationsausschnitt aus einem System als Grundlage für eine Dokumentation zu nutzen.

Hier besteht jedoch immer die Gefahr, einen Wert zu übersehen und reale Details abzubilden. Besser ist, von Anfang an eine künstliche Beispielumgebung aufzusetzen. So sollte ein Demo-Account mit Beispielnamen und -kontakten verwendet werden, statt eines echten Accounts.

Bei der Nutzung in Produktivumgebungen, wie als E-Mail-Absender, sollten die eigenen Domains genutzt werden. So kann sichergestellt werden, dass auch Rückläufer für noreply-Adressen nicht ins Leere laufen oder unbeabsichtigt Dritte erreichen.

Fazit

Beispiel ist nicht gleich Beispiel. Bei der Nutzung von Beispielen in Dokumentationen, anderen Texten, Medien oder Applikationen sollte Vorsicht geboten sein.

Handelt es sich um Beispiele, oder fiktive Werte, so sollten dafür vorgesehenen Varianten, wie z.B. Drama Numbers, verwendet werden.

Durch die Nutzung von Beispiel-IP-Adressen wird vermieden, dass Beispiel-Skripte, Konfigurationen oder Tutorien ungewollt fremde Rechner scannen oder ansprechen. Auch wenn ein Nutzer einen in einer Anleitung gezeigten Befehl kopiert, sind diese Adressen harmlos, da sie ins Leere führen oder nur lokale Wirkung haben.

Von inoffiziellen Beispieldomains wie beispiel.de sollte abgeraten werden, da hier keine Kontrolle darüber besteht, wie lange sie noch ihrer Funktion als Beispiel entspricht. Bei den hierfür offiziell reservierten Ressourcen kann hingegen von einer gewissen Kontinuität ausgegangen werden.

Beispieldomains, reservierte IP-Adressen und Drama Numbers sind essenziell für sichere und verständliche Dokumentationen sowie Testumgebungen. Durch die Verwendung standardisierter Werte können Fehler vermieden, Datenschutzrisiken minimiert und die Konsistenz in technischen Dokumentationen gewährleistet werden.

Die Einhaltung der entsprechenden RFCs und Best Practices hilft, Missverständnisse und missbräuchliche Nutzungen zu vermeiden.

Dieser Artikel erschien ursprünglich auf Golem.de und ist hier in einer alternativen Variante zu finden.

Coding Conventions

Die Entwicklung von Software zeichnet sich in der heutigen Welt oft dadurch aus, dass sie unter Mitwirkung unterschiedlichster Entwickler bewerkstelligt wird. Im Rahmen einer solchen Entwicklung kommt es darauf an, bestimmte Standards und Best Practices einzuhalten.

Neben dem passenden Workflow kommen hier Coding Conventions zum Tragen und bilden einen wichtigen Baustein um Quelltext effizienter, lesbarer und zuverlässiger zu gestalten.

Was sind Coding Convention?

Eine Coding Convention definiert sich über bestimmte Stilregeln und Best Practices, bezogen auf eine Programmiersprache. Innerhalb der Konvention werden viele Aspekte der Programmiersprache und ihrer sprachlichen Elemente behandelt. Dies fängt bei Regeln zur Formatierung an, führt sich fort mit der Benamung von Variablen und anderen Strukturen und erstreckt sich auch auf andere Bereiche, wie Reihenfolgen und Zeilenlängen.

Warum werden sie benötigt?

Nun kann sich natürlich die Frage gestellt werden, warum eigentlich Coding Conventions benötigt werden?

Neben offensichtlichen Gründen, dass sie vielleicht eine Anforderung des Kunden sind, gibt es auch andere Gründe für diese Konventionen. So werden die meisten Projekte nicht von einer einzelnen Person betreut und für die Entwickler eines Produktes ist es einfacher, wenn der Quelltext nach identischen Standards entwickelt wurde. Dies ermöglicht eine schnellere Einarbeitung und hilft auch bei anderen Dingen, wie der Verminderung von Merge-Konflikten bei der Arbeit mit Versionskontrollsystemen.

Damit tragen diese Konventionen dazu bei, die Zusammenarbeit zwischen Entwicklern zu erleichtern, indem sie eine einheitliche und konsistente Basis schaffen.

Eine Welt ohne Coding Conventions

Natürlich können Programme auch ohne Coding Conventions geschrieben werden. Dies kann zu interessanten Programmen führen:

#include 

...

yeet Yeet Yeeet yeeeT 
Yeeeet
yEet yEEt yeEt yyeet yeett yeetT
yeeT yet yeetT
yeeeeT

Bei diesem Programm stellen sich bei der Betrachtung mehrere Fragen. In welcher Sprache ist es geschrieben? Ist es überhaupt lauffähig? Und was ist der eigentliche Zweck des Quelltextes?

In diesem Beispiel wurde das C-Programm so gestaltet, dass es möglichst unlesbar ist, indem mit entsprechenden Definitionen gearbeitet wurde, welche anschließend im Quelltext genutzt werden.

#define yeet int
#define Yeet main
#define yEet std
#define yeEt cout
#define yeeT return
#define Yeeet (
#define yeeeT )
#define Yeeeet {
#define yeeeeT }
#define yyeet <<
#define yet 0
#define yeett "Yeet!"
#define yeetT ;
#define yEEt ::

Es zeigt auf, dass ohne einheitliche Coding Conventions im besten Fall Chaos droht. Auf die Spitze treibt das auch der International Obfuscated C Code Contest, bei welchem es darum geht, Quelltext möglichst so zu verschleiern, dass nur schwer zu erraten ist, welche Funktion dieser am Ende in sich trägt.

Eine Implementation des zcat-Kommandos

In diesem Beispiel wird der Befehl zcat zur Darstellung mittels gz-komprimierter Daten implementiert. Auch ohne solche Extrembeispiele würde in einer Welt ohne Coding Conventions eine Menge an inkonsistentem Code entstehen:

int counterServer = 1               ;
int counterClient = 2               ;
int counterDevice = 3               ;
int test1 = 4                       ;

Natürlich kann ein Quelltext so formatiert werden, aber in den meisten Fällen erschwert dies die Lesbarkeit des Quelltextes enorm. Auch die Nutzung von Whitespaces und falscher Einrückung kann zu Problemen führen:

if        (system==true) {
    doSomething()        ;
doFoobar                       ();
}

Auch Richtlinien über Komplexität sind ein wichtiger Bestandteil, solcher Konventionen. Gegeben sei folgendes Programm:

#include

main(){
  int x=0,y[14],*z=&y;*(z++)=0x48;*(z++)=y[x++]+0x1D;
  *(z++)=y[x++]+0x07;*(z++)=y[x++]+0x00;*(z++)=y[x++]+0x03;
  *(z++)=y[x++]-0x43;*(z++)=y[x++]-0x0C;*(z++)=y[x++]+0x57;
  *(z++)=y[x++]-0x08;*(z++)=y[x++]+0x03;*(z++)=y[x++]-0x06;
  *(z++)=y[x++]-0x08;*(z++)=y[x++]-0x43;*(z++)=y[x]-0x21;
  x=*(--z);while(y[x]!=NULL)putchar(y[x++]);
}

Bei diesem handelt es sich um ein einfaches Hello World-Programm, aber das Verständnis wird durch die Umsetzung, genauer gesagt dessen unnötige Komplexität, sehr erschwert.

Auch wenn sich auf Einrückungen geeinigt wird, ist dies nicht immer sinnvoll:

function f() {
  doThings();
  doMoreThings();
             }

Bei diesem Beispiel wird eine Einrückung genutzt, welche ungebräuchlich ist und bei den meisten Entwicklern wahrscheinlich auf Ablehnung stoßen wird und nicht dazu führt, dass der Quelltext übersichtlicher wird.

Die Benamung von Elementen ist ein wichtiger Teil von Coding Conventions:

void doSomeTHING() {
  int test1 = 1;
  int TEST2 = 2;
  int teST3 = 3;
}

void DoSomething() {
  int tEST4 = 4;
}

Wird bei dieser nicht auf Konsistenz geachtet, trägt dies nicht zum besseren Verständnis bei. Auch Kommentare, bzw. das Schreiben derselben sind eine Aufgabe, bei der sorgfältig gearbeitet werden sollte:

try {
  ...
} catch(Exception e) {
  // Gotta Catch 'Em All
}

Natürlich ist Humor im echten Leben wichtig, aber in einem Quelltext sollte er nichts zu suchen haben. Stattdessen sollte sich hier auf die Fachlichkeit bezogen werden.

Auch die Nutzung unüblicher Vorgehensweisen bzw. das Verstecken bestimmter Operationen erschwert das Verständnis eines Quelltextes:

int main() {

  String helloWorld = "Hello World!";
  cout << helloWorld << endl;

  String hello = (helloWorld, 5);
  cout << hello << endl;

  system("pause");
  return 0;
}

Ohne weitere Informationen ist es relativ schwer herauszufinden, was in diesem Beispiel passiert. Hier werden die ersten fünf Stellen der Zeichenkette Hello World! zurückgegeben. In diesem Fall geschieht dies über die Überladung des Komma-Operators:

using namespace std;

#define String string

String operator,(String lhs, int rhs) {
  lhs.erase(lhs.begin() + rhs, lhs.end());
  return lhs;
}

Auch eine schlechte Benennung und ein Sprachmischmasch kann das Verständnis des Quelltextes erschweren:

#include 

gibHalloWeltAus()
{
    // use cout for output
    cout << "Hello World!" << endl;

    // Rückgabereturn
    return 0;
}

Ziele von Coding Conventions

Wenn sich diese Beispiele aus der Welt ohne Coding Conventions angeschaut werden, können aus diesen einige Ziele für entsprechende Konventionen abgeleitet werden.

Es geht darum, dass Coding Conventions bewährte Praktiken abbilden und für einen lesbaren und verständlichen Quelltext sorgen. Sie sollen die Zusammenarbeit im Team erleichtern und eine gewisse Einheitlichkeit herstellen.

Daneben sind Coding Conventions und das Konzept von Clean Code miteinander verbunden. Clean Code ist ein Konzept, das sich auf die Softwareproduktion und das Programmierdesign bezieht. Es legt fest, dass Quelltext so geschrieben werden sollte, dass er einfach zu lesen, zu verstehen und zu warten ist. Die Einhaltung von Coding Conventions kann dazu beitragen, diese Kriterien einzuhalten.

Elemente von Coding Conventions

Doch woraus genau bestehen Coding Conventions im Einzelnen? Im ersten Schritt sollte sich bewusst gemacht werden, dass sich solche Konventionen von Sprache zu Sprache unterscheiden. Auch wenn sich im Laufe der Zeit einige Standards herauskristallisiert haben, können diese nicht immer eins zu eins auf die eigenen Anforderungen angewendet werden.

Unterschiedliche Elemente von Coding Conventions

Im Einzelnen setzen sich Coding Conventions aus Elementen zusammen, welche im folgenden genauer besprochen werden sollen.

Benamung

Ein essenzielles Element ist die Benamung innerhalb eines Entwicklungsprojektes. Dies fängt bei Dateinamen und Verzeichnissen an, zieht sich hin zu Bezeichnern, wie den Namen von Variablen, Klassen und vielen anderen Elementen.

Grundsätzlich sollte bei der Benamung von Elementen immer so viel wie nötig und so wenig wie möglich benannt werden.

Dateinamen

Da Coding Conventions sich von Sprache zu Sprache unterscheiden, existieren bereits Unterschiede auf Ebene der Dateinamen. Während Dateien von C-Programmen meist in Kleinschreibung benannt werden:

main.c
tilerenderer.c

sieht dies bei Java-Applikationen anders aus:

Main.java
TileRenderer.java

Neben den Dateinamen bezieht sich dies auch auf die Benamung und Struktur von Verzeichnissen. In C würde dies wie folgt aussehen:

src
  engine
  renderer
  utils

während in Java meist die Struktur des Packages abgebildet wird. Bei dem Package com.example.transformer.html würde die entsprechende Verzeichnisstruktur wie folgt aussehen:

src
  main
    java
      com
        example
          transformer
            html
            markdown
  test

Eine weitere Eigenart von Java ist, dass die Namen der Packages eine Domain-Struktur abbilden und z. B. mit der Domain der Firma beginnen.

Neben den Coding Conventions für die jeweilige Sprache gehen bei der Strukturierung des Projektes auch noch andere Aspekte ein. Wird z. B. mit dem Build-Werkzeug Maven gearbeitet, so gilt dort Konvention vor Konfiguration.

Bei Maven bedeutet dies, dass eine Reihe von Standardregeln existieren, die vom Benutzer des Werkzeuges befolgt werden müssen, um ein Projekt erfolgreich zu erstellen. So muss ein Projekt in einer bestimmten Struktur organisiert sein, damit Maven es erfolgreich verarbeiten kann. Diese Standards erleichtern es, ein Projekt mit Maven zu erstellen, da der Benutzer nicht jeden einzelnen Schritt konfigurieren muss.

Sprechende Namen

Auch bei der Benamung sollten gewissen Standards eingehalten werden:

int a = getSum();

In diesem Fall wird eine Methode mit dem Namen getSum aufgerufen und das Ergebnis in der Variable a gespeichert. Hier sollte mit sprechenden Namen gearbeitet werden. Solche Namen zeichnen sich dadurch aus, dass sie beim Lesen bereits Aufschluss über ihre Fachlichkeit und deren Bedeutung geben:

int sum = getSum();

Damit wird klar, dass sich in der Variable sum eine entsprechende Summe befindet. Theoretisch kann die Benennung natürlich noch weiter spezifiziert werden:

int sumArticles = getSum();

Unter Umständen können Namen hierbei etwas länger werden, aber dafür wird Klarheit gewonnen. Diese Art der Benamung sollte nicht nur für Variablen, sondern generell für Bezeichner, wie Klassennamen gelten.

Allerdings keine Regel ohne Ausnahme, z. B. bei Exceptions unter Java:

try {
  // Try some funky stuff
} catch(Exception e) {
  // Handle exception
}

Dort hat es sich eingebürgert, einer Exception den Namen e bzw. ex zu geben. Sind solche Konventionen vorhanden und weitverbreitet, sollten diese entsprechend eingehalten werden. Auch hier dient das Einhalten dieser Regeln dazu, die Lesbarkeit und Wartbarkeit des Quelltextes zu erhöhen.

Verbotene Bezeichner

Es gibt eine Reihe von Bezeichnungen, welche in der Theorie, je nach verwendeter Sprache, verwendet werden können, es aber nicht sollten.

So ist es in Sprachen wie C# möglich, mit einem vorgestellten At-Zeichen Schlüsselwörter der Sprache als Bezeichner verwenden zu können. Um Verwirrung und darauf aufbauende Probleme zu vermeiden, sollte dies unterlassen werden.

Andere Bezeichner, wie handle, sollten nur in einem eng begrenzten Kontext oder einer entsprechenden Fachlichkeit benutzt werden.

Auch die Nutzung von Variablen mit dem Namen temp oder tmp sollte unterlassen werden, da meist eine entsprechend sinnvollere fachliche Benamung möglich ist.

Schleifen und Benamung

Wie bei Exceptions haben sich auch bei Schleifen bestimmte Konventionen zur Benamung eingebürgert, an welche sich gehalten werden sollte:

for(int i = 0; i < 10; i++) {

    for(int j = 0; j < 10; j++) {

      // Do stuff
    }
}

So wird die Zählervariable bei Schleifen mehrheitlich mit dem Namen i benannt und wenn in der Schleife weitere Schleifen geschachtelt werden, so werden diese fortlaufend mit j, k und so weiter benannt.

Aber auch hier kann in Ausnahmen davon abgewichen werden. Ein Beispiel hierfür wäre z. B. die Verarbeitung eines Bildes:

for(int y = 0; y < image.height; y++) {

    for(int x = 0; x < image.width; x++) {

      // Do image stuff
    }
}

Hier wird sich auf die x- und y-Achse des Bildes bezogen und durch die entsprechende Benamung kann sinnvoll mit diesen in der eigentlichen Logik der Schleife gearbeitet werden.

Kamele, Dromedare und Schlangen

Bezeichner können wie bei obigem Beispiel einfache Namen bestehend aus einem Wort sein, bestehen aber in vielen Fällen aus mehreren Wörtern.

Unterschiedlichste Schreibvarianten bei zusammengesetzten Bezeichnern

Um diese sinnvoll miteinander zu verbinden werden je nach Sprache unterschiedliche Varianten von Binnenmajuskeln benutzt, welche je nach Verwendung treffende Namen wie CamelCase und Ähnliche tragen. Diese Schreibweise sorgt letztlich für eine bessere Lesbarkeit, da sie einzelne Wörter sinnvoll voneinander abgrenzt.

Binde- und Unterstriche

Neben der Schreibweise mittels Binnenmajuskeln existieren auch andere Schreibweisen, was sich im Beispiel wie folgt darstellt:

do_things_fast();
do-things-fast();

So wird in Sprachen wie C und Perl auch auf Unterstriche zurückgegriffen und auch in PHP war dies bis zur Version 4 der Fall. Die Schreibweise mit dem Bindestrich, welche auch als lisp-case bekannt ist, wurde unter anderem in COBOL und Lisp genutzt.

Auch bei Rust wird teilweise auf Unterstriche als auch auf CamelCase gesetzt.

Ausnahmen bei der Benamung

Je nach Sprache wird damit meist eine bestimmte Schreibweise für Bezeichner wie den Namen von Variablen genutzt, allerdings existieren hiervon auch Ausnahmen bzw. Abweichungen, wie bei der Definition von Konstanten:

public static final String SECRET_TOKEN = "X7z4nhty3287";

Diese werden in vielen Fällen komplett großgeschrieben und meist mit Unterstrichen unterteilt. Auch hier gilt wieder, dass solche Konstanten möglichst sprechend benannt werden sollten und auf Abkürzungen und Ähnliches verzichtet werden sollte.

Prä- und Suffixe

In der Vergangenheit wurden an Bezeichner teilweise Prä- und Suffixe mit angetragen. Begründet war dies mit den damaligen Compilern und der fehlenden Unterstützung in der Entwicklungsumgebung. Durch die Nutzung eines Präfixes konnte so z. B. der Typ einer Variable aus dem Namen ermittelt werden.

Die sicherlich bekannteste Notation ist die Ungarische Notation. Hier werden die Bezeichner aus einem Präfix für die Funktion, einem Kürzel für den Datentyp und einem Bezeichner zusammengesetzt.

Ein Beispiel für einen solchen Namen wäre die Variable idValue, welche anzeigt, dass es sich um einen Index vom Typ Double handelt, welcher den Namen Value trägt.

Mittlerweile wird diese Notation in der Praxis nur noch selten genutzt. Auch Linus Torvalds hatte sich dazu geäußert:

Encoding the type of a function into the name (so-called Hungarian notation) is brain damaged – the compiler knows the types anyway and can check those, and it only confuses the programmer.

Neben der besseren Unterstützung der IDEs gibt es andere Gründe, welche gegen eine Nutzung der ungarischen Notation sprechen. So kann z. B. bestehender Quelltext schlechter migriert werden, wenn sie die Namen nicht ändern dürfen, aber die Typen dies tun. Dies war z. B. der Fall bei der Umstellung der WinAPI auf eine 64-Bit fähige API, bei dem Namen nun nicht mehr auf den korrekten Datentyp hinweisen.

Einrückungen

Neben der Benennung von Bezeichnern ist auch die Einrückung ein unter Umständen recht emotionales Thema.

Dabei geht es hauptsächlich darum, ob Leerzeichen oder Tabulatoren für die Einrückungen genutzt werden. Aus pragmatischer Sicht sollte hier insbesondere die Mischung dieser beiden Varianten verhindert werden.

Für Leerzeichen spricht, dass die Einrückungen bei allen Nutzern identisch aussehen. Im Gegensatz zu Tabulatoren benötigen Leerzeichen, mehr Speicher. Vier Leerzeichen belegen 4 Byte, ein Tabulator nur ein Byte.

Bei Tabulatoren kann der Einzug in der Entwicklungsumgebung individuell konfiguriert werden, was aber gleichzeitig den Nachteil ergibt, dass der Quelltext bei unterschiedlichen Mitarbeitenden anders aussehen kann.

Persönlich würde der Autor an dieser Stelle immer Leerzeichen empfehlen. Damit ist ein Quelltext gewährleistet, welcher bei jedem Entwickler identisch aussieht. Der zusätzliche Speicherbedarf kann hierbei vernachlässigt werden.

Einrückungstiefen

Bei der Frage der Leerzeichen stellt sich auch die Frage, mit wie vielen Leerzeichen soll ein Block eingerückt werden. Hier ergibt sich die Möglichkeit, dies mit zwei Leerzeichen je Block zu machen:

void main() {
  doSomething();
}

Der Standard bei vielen Projekten sind hingegen vier Leerzeichen:

void main() {
    doSomething();
}

Allerdings sind auch acht Leerzeichen gebräuchlich, z. B. beim Linux-Kernel. Wirklich bemerkbar wird dies allerdings erst dann, wenn mehrere Blöcke ineinander verschachtelt werden:

void main() {

    for(int i = 0; i < 10; i++) {

        for(int j = 0; j < 10; j++) {

            doSomething();
        }
    }
}

Je nach Ausgabeformat, z. B. beim Ausdruck oder in Präsentationen ist es sinnvoll auf zwei Leerzeichen zu setzen, aber im Allgemeinen sollten vier Leerzeichen genutzt werden.

Whitespaces und Leerzeilen

Neben der Einrückung sind auch die Whitespaces im Quelltext selbst, sowie Leerzeilen ein Element zur Strukturierung des Quelltextes.

Leerzeilen stellen ein wichtiges Element zur Strukturierung dar. Natürlich kann ein Quelltext ohne Leerzeilen geschrieben werden und leider ist dies in der Praxis oft zu sehen. Sinnvoll ist es aber, den Quelltext etwas weiträumiger zu gestalten:

int getResult(int a, int b) {

    int sum = getSum();
    int ret = 0;

    for(int i = 0; i < 10; i++) {
        ret += sum;
    }

    return ret;
}

Die Trennung einzelner Bestandteile des Quelltextes durch Leerzeilen sollte anhand der funktionalen Blöcke bzw. nach der Fachlichkeit vorgenommen werden.

Neben den Leerzeilen, sind auch Whitespaces ein essenzieller Teil der Formatierung eines Quelltextes. Whitespaces definieren sich allgemein als Leerstellen in Text, Code oder Schrift, die zwischen Zeichen, Wörtern, Zeilen oder Absätzen liegen. In der Programmierung werden Whitespaces auch als Formatierung verwendet, um den Quelltext leserlicher zu machen und den Code übersichtlicher zu strukturieren.

Whitespaces verbessern die Sichtbarkeit und das Verständnis der Syntax:

int sum=a+b;

for(int i=0;i<10;i++) {
    doSomething();
}

Bei diesem Beispiel wäre es wesentlich sinnvoller, Leerzeichen zum Strukturieren zu nutzen und dem Quelltext eine gewissen Luftigkeit zu geben:

int sum = a + b;

for(int i = 0; i < 10; i++) {
    doSomething();
}

Dies erhöht die Lesbarkeit und sorgt letztlich für ein besseres Verständnis. Natürlich kann auch an dieser Stelle übertrieben werden:

for ( int i = 0; i < 10; i++ ) {
    doSomething ( ) ;
}

So werden hier auch Leerzeichen rund um die Klammern gesetzt, was im Normalfall nicht sonderlich hilfreich ist und deshalb unterlassen werden sollte.

Blockklammern

In vielen Programmiersprachen wird mit Blöcken gearbeitet. Ein Block definiert sich als eine Gruppe von Anweisungen, die als eine Einheit behandelt werden. So wird über den Block z. B. der Gültigkeitsbereich von Variablen definiert. Ein Block beginnt normalerweise mit einer öffnenden geschweiften Klammer und endet mit einer schließenden Klammer gleichen Typs.

Beispielsweise kann ein Block zu einer if-Anweisung gehören, in der eine Reihe von Anweisungen ausgeführt werden, wenn die Bedingung wahr ist. Hier kann natürlich die Frage nach der Notwendigkeit gestellt werden, wie in diesem Stück Java-Code:

if(something == true)
    doFooBar();

So würde dieses Beispiel ohne Probleme kompilieren und wenn die Bedingung zutrifft, die Methode doFooBar aufgerufen werden. Problematisch wird dieses Konstrukt allerdings dann, wenn der Quelltext an dieser Stelle erweitert wird:

if(something == true)
    doAnotherThing();
    doFooBar();

Nun würde nur noch die Methode doAnotherThing ausgeführt werden. Die andere Methode hingegen nicht mehr. Aus dem Quelltext ist dies allerdings nicht ohne Weiteres ersichtlich. Aus diesem Grund sollte immer mit Blockklammern gearbeitet werden, auch wenn nur eine einzelne Anweisung folgt:

if(something == true) {
    doFooBar();
}

Dadurch werden Fehler vermieden und die Intention des Quelltextes wird sofort ersichtlich.

Position der Klammern

Für die Positionierung der geschweiften Blockklammern gibt es in der Praxis zwei verbreitete Varianten, diese zu setzen. Bei der ersten Variante sind sie beide auf der gleichen Ebene zu finden:

boolean get()
{
    int a = 7;
    int b = 42;

    int result = doFooBar(7, 42);

    if(result == 23) 
    {
        return false;
    }

    return true;
}

Der Vorteil an dieser Variante ist, dass sofort zu sehen ist, wo ein Block beginnt und wo sich die entsprechende schließende Klammer des jeweiligen Blockes befindet. Als Nachteil wird bei dieser Variante oft aufgeführt, dass damit etwas Platz verschwendet wird.

Bei der anderen gebräuchlichen Variante wird die öffnende Klammer eines Blockes direkt hinter die Anweisung gesetzt, welche zum öffnenden Block gehört:

boolean get() {

    int a = 7;
    int b = 42;

    int result = doFooBar(7, 42);

    if(result == 23) {
        return false;
    }

    return true;
}

Dies erschwert zwar die Zuordnung zwischen dem Beginn des Blockes und dem Ende, allerdings zeigen die meisten modernen IDEs diese Zuordnung prominent an.

In der Theorie wird bei dieser Variante eine Zeile eingespart, allerdings ist es sinnvoll nach der öffnenden Blockklammer eine Leerzeile zu setzen, um die Übersichtlichkeit zu erhöhen.

Häufig wird noch ein Unterschied zwischen einzeiligen und mehrzeiligen Blöcken gemacht:

if(something == true) {
    doFooBar();
}

Dort wird die Leerzeile weggelassen, während sie bei mehrzeiligen Blöcken immer eingefügt wird:

if(something == true) {

    doFooBar();
    doSomething();

    for(int i = 0; i < 10; i++) {
        doThings();
    }    
}

Blöcke per Einrückung

Neben Sprachen mit solchen Blockklammern existieren auch Sprachen wie Python, welche andere Wege zur Strukturierung von Blöcken nutzen:

import sys
import random

running = True

while running:

    randomNumber = random.randint(0,8)

    if randomNumber == 0:
        break;
        
    else:
        print(randomNumber)

Hier wird die Zuordnung zu einem Block über die entsprechende Einrückung vorgenommen. Damit entfällt die Frage nach der Position der Blockklammern.

Reihenfolgen

In vielen Programmiersprachen gibt es Schlüsselwörter, wie Modifikatoren für die Sichtbarkeit. Für diese empfiehlt es sich auch eine entsprechende Reihenfolge zu definieren und diese einzuhalten.

Am Beispiel von Java wäre dies die Sichtbarkeit, dann eine eventuelle static-Definition gefolgt von einer final-Definition und am Ende der eigentlichen Definition:

public int a = 7;
public final int b = 24;
public static final int c = 42;

Auch bei Systemen zur statischen Codeanalyse, wie Sonarlint, sind solche Regeln hinterlegt.

Reihenfolge im Quelltext

Neben den Namen der Bezeichnern sind je nach Sprache auch bestimmte Reihenfolgen der einzelnen Elemente gewünscht. Unter Java ist dies vornehmlich folgende Reihenfolge: Konstanten, private Variablen, private Methoden, Getter und Setter und anschließend öffentliche Methoden.

Allerdings kann es valide sein, Public-Methoden und Private-Methoden zusammenzuhalten, wenn diese z. B. nach Funktionalität gruppiert sind.

Zeilenlänge und Umbrüche

Früher gab es relativ strenge Regeln, was die maximale Zeilenlänge innerhalb eines Quelltextes anging. Meist waren dies 80 Zeichen pro Zeile, bedingt durch die 80 Spalten in der Hollerith-Lochkarte von IBM. Daneben haben sich mittlerweile Zeilenlängen von 80 über 100 bis zu 120 Zeichen pro Zeile eingebürgert.

Auch in Zeiten größerer Bildschirme und höherer Auflösungen, sollten Zeilen trotzdem nicht unendlich lang gestaltet werden, sondern mit Zeilenumbrüchen gearbeitet werden. Für solche Umbrüche existieren unterschiedliche Variante, welche in gewisser Hinsicht Geschmacksache sind.

public int calculate(int valueA,
                     int valueB,
                     int valueC,
                     int valueD,
                     int valueE,
                     int valueF,
                     int valueG) {
    return 0;
}

Grundsätzlich sollten keine Umbrüche mitten in einer Parameterliste vorgenommen werden, sondern die Parameter einzeln umgebrochen werden. Auch bei Fluent Interfaces wird mit Zeilenumbrüchen gearbeitet:

CarBuilder carBuilder = new CarBuilder()
        .withWheels(4)
        .withEngine(400, Fuel.DIESEL)
        .withWindows(5)
        .build();

Die Umbrüche verbessern, richtig eingesetzt, die Lesbarkeit und Verständlichkeit des Quelltextes.

Kommentare

Für einen verständlichen Quelltext sind in vielen Fällen Kommentare in diesem nötig und wichtig.

Je nach Sprache werden unterschiedliche Möglichkeiten für Kommentare bereitgestellt. Vorwiegend sind dies Zeilenkommentare und Blockkommentare.

Blockkommentare sind eine Reihe von Kommentaren, die durch ein vorangestelltes /* und ein abschließendes */ angezeigt werden, sodass mehrere Zeilen Text zusammen kommentiert werden können. Zeilenkommentare sind Kommentare, die nur eine einzelne Zeile betreffen und mit // beginnen. Sie können am Ende einer Codezeile oder auf einer eigenen Zeile platziert werden. Beide Kommentartypen sind nützlich, um das Verständnis des Codes zu erleichtern, indem sie Erklärungen zu bestimmten Codeabschnitten bereitstellen.

In den meisten Fällen sollten innerhalb eines Quelltextes den Zeilenkommentaren der Vorrang eingeräumt werden, entweder zum Auskommentieren von Quellcode oder zum Dokumentieren innerhalb des Codes:

// Create system temporary directory
Path tmpdir = null;

// log.error(tmpdir);

Block-Kommentare werden oft für die Dokumentation von Methoden, z. B. mittels JavaDoc genutzt:

/**
 * This method returns an Optional that holds a String containing
 * the file extension of the passed filename.
 * @param filename The file name whose extension is to be determined.
 * @return Optional filled with a String with the file extension if 
 * the file has an extension, or an empty optional if it has no extension.
 */

Grundsätzlich gilt bei Kommentaren, dass sie fachlicher Natur sein sollten und dass nicht unnötig kommentiert wird. Als Sprache bietet sich hier wie bei der Benamung von Bezeichnern Englisch als kleinster gemeinsamer Nenner an. Unnötige Kommentare sollten vermieden werden:

// Calculate sum and store in sum
int sum = getSum(a, b);

Der Inhalt des Kommentars ergibt sich bereits aus der sprechenden Bezeichnung der Variablen und der dazugehörigen Methode, sodass dies nicht noch einmal mit einem Kommentar untermauert werden muss.

Interessanter wäre es hier, wenn der Kommentar noch etwas zur Fachlichkeit beiträgt:

// Calculate sums of base articles
int sum = getSum(a, b);

Auch das beliebte Auskommentieren von Code wird mittels der Sprachmittel des Kommentars ermöglicht. Im Normalfall sollte auskommentierter Quellcode am Ende immer entfernt werden und nicht im Quelltext verbleiben.

Allgemeine Regeln

Neben Regeln für spezielle Konstrukte existieren eine Reihe von allgemeinen Regeln, welche auch in Coding Conventions Einzug gefunden haben.

So gilt, dass pro Zeile genau eine Anweisung bzw. ein Statement kodiert wird, eine Funktion bzw. eine Methode genau eine Aufgabe erledigen und Klassen und Methoden eine gewisse Größe nicht überschreiten sollten.

Bei Klassen definiert sich hier meist eine maximale Größe von 2000 Zeilen, während bei Methoden gerne gesagt wird, dass eine Methode als Ganzes auf den Bildschirm passen sollte.

Aufgaben für Methoden

Auch die Beschränkung von Methoden auf eine Aufgabe ist eine sinnvolle Regel. So verheißt eine Methode mit dem Namen doItAll() schon wenig Gutes. Hingegen definiert folgende Methode:

int getSum(int a, int b)

schon anhand ihres Namens klar, welche Aufgabe sie wahrnimmt und mit welchem Ergebnis zu rechnen ist.

Dadurch, dass Funktionen bzw. Methoden sich nur auf eine Aufgabe beschränken, sind sie besser wiederverwendbar und verhindern in vielen Fällen doppelten Quelltext. Auch das Review solcher fachlich eng abgestimmten Methoden ist einfacher möglich, da die Komplexität verringert ist.

Coding Conventions

Während bis hierhin viele einzelne Elemente beschrieben wurden, sollen diese nun zu einer Coding Convention zusammengeführt werden. Solche Coding Conventions sind relativ umfangreiche Werke. In vielen Fällen ist es nicht nötig das Rad neu zu erfinden, da für viele Sprachen Standard-Konventionen existieren, welche genutzt werden können.

Alternativ sollte sich zumindest an diesen Konventionen orientiert werden. Auch die jeweiligen Entwicklungsumgebungen, setzten über die Code-Formatierung gewisse Teile von Coding Conventions direkt um.

Sprachspezifische Konventionen

Wer sich umschaut, wird feststellen, dass eine Reihe von Coding Conventions für unterschiedliche Sprachen existieren. Dies sind unter anderem die .NET: Microsoft Coding Conventions, für Java die Code Conventions for the Java Programming Language und für PHP: PSR-1 und PSR-2.

Allerdings werden manche dieser Konventionen wie für Java mittlerweile als veraltet angesehen und büßen damit auch an Verbindlichkeit ein. Bei anderen Styles wie PSR-2 werden diese direkt für die Entwicklung des Frameworks genutzt und sind somit verbindlich.

Übergreifende Konventionen

Daneben existieren noch andere Coding Conventions wie die Apple Coding Convention und der Google Style Guide.

Der Google Style Guide deckt Konventionen für unterschiedlichste Sprachen, wie C++, Objective-C, Java, Python, R, HTML, JavaScript und weitere ab und kann online eingesehen werden.

Lizenziert ist der Google Style Guide unter der Creative-Commons-Lizenz CC-BY. Neben der eigentlichen Beschreibung werden auch Dateien mit den entsprechenden Konfigurationen für die Entwicklungsumgebung mitgeliefert.

Dokumentation

Auch wenn ein Hauptaugenmerk bei Coding Conventions auf dem Quelltext liegt, sollte die Dokumentation ebenfalls beachtet werden. So sollte nur das notwendige dokumentiert und tote und inkorrekte Dokumentation gelöscht werden.

Auch hat es sich eingebürgert, eine entsprechende Datei ins Wurzelverzeichnis des Projektes zu legen. Diese trägt meist den Namen README bzw. README.md

In diesem Dokument wird erklärt, um welches Projekt es sich handelt und ein kurzer Überblick über das Projekt gegeben. Daneben werden weiterführende Links bereitgestellt und erklärt, wie das Projekt gebaut werden kann.

# WordPress2Markdown

WordPress2Markdown is a tool that convert WordPress eXtended RSS (WXR) into markdown. Export the WordPress site via
backend and use the WordPress eXtended RSS (WXR) with this tool.

## Usage

WordPress2Markdown is a command line tool.

> java -jar WordPress2Markdown.jar -i wordpress-export.xml -s DATETIME -o /home/seeseekey/MarkdownExport

### Parameter

The options available are:

    [--author -f value] : Filter export by author
    [--authors -a] : Export authors
    [--help -h] : Show help
    [--input -i value] : Input path
    [--output -o value] : Output path
    [--scheme -s /POST_ID|DATETIME/] : Scheme of filenames

## Conversion

WordPress2Markdown converted the following html and other tags:

* \<em\>
* \<b\>
* \<blockquote\>
* \<pre\>
* \<img\>
* \<a\>
* Lists
* WordPress caption blocks ()

All other tags are striped.

## Developing

Project can be compiled with:

> mvn clean compile

Package can be created with:

> mvn clean package

## Authors

* seeseekey - https://seeseekey.net

## License

WordPress2Markdown is licensed under AGPL3.

Eine weitere wichtige Datei ist das Changelog, bzw. die Datei CHANGELOG.md. Diese Datei dokumentiert Änderungen am Projekt und informiert den Leser somit über Änderungen, neue Funktionalität und Ähnliches.

# Changelog

This changelog goes through all the changes that have been made in each release.

## [1.2.0-SNAPSHOT]() - 2022-03-04

### Added

* Implement simple conversion for CSV files

### Changed

* Update project to Java 17
* Rework changelog
* Update dependencies
* Change license from GPL3 to AGPL3

### Fixed

* Fix some SonarLint code smells
* Small optimizations

## [1.1.0](https://github.com/seeseekey/Convert2Markdown/releases/tag/v1.1) - 2019-10-13

### Added

* Implement conversion of MediaWiki dump files
* Add statistical information for export
* Add support for exporting author (#1)
* Add filter to export only a specific author

### Changed

* Rename tool to Convert2Markdown
* Update documentation
* Rebuild HTML to markdown conversion with HTML parser

## [1.0.0](https://github.com/seeseekey/Convert2Markdown/releases/tag/v1.0) - 2019-03-26

* Initial release

Versionierung

Im weiteren Sinne gehört auch die Versionierung des Projektes zu den Coding Conventions. Gerne genutzt wird hierbei die semantische Versionierung. Dabei liegen den Zahlen der Versionnummer z. B. 2.4.7 eine bestimmte Bedeutung zugrunde.

So handelt es sich bei der ersten Zahl um die Major-Version, welche nur dann erhöht wird, wenn zur Vorgängerversion inkompatible Änderungen oder andere signifikanten Änderungen vorgenommen wurden.

Die zweite Zahl ist die sogenannte Minor-Version, welche meist bei neuer Funktionalität hochgezählt wird. Die letzte Zahl bezeichnet die Bugfix-Version und wird bei entsprechenden Fehlerbereinigungen hochgezählt.

Daneben existieren auch andere Versionierungen, wie das relativ beliebte Schema Jahr.Monat z. B. 2023.04 als Versionnummer, welche bei neuen Releases basierend auf der Version gerne um eine dritte Nummer erweitert werden z. B. 2023.04.1.

Umsetzung

Neben der eigentlichen Definition einer Coding Conventions ist es wichtig, dass diese im Entwicklungsalltag berücksichtigt und genutzt wird. Hier stellt sich dann die Frage nach der organisatorischen Umsetzung.

Grundlegend sind es einige Schritte auf dem Weg bis zu Nutzung und Umsetzung. So sollte sich im ersten Schritt auf eine Coding Convention geeinigt werden. Nachdem dies geschehen ist, mitsamt aller diesbezüglicher Regeln, wie zur Benennung oder der gewünschten Komplexität, müssen diese Coding Conventions entsprechend kommuniziert werden.

So ist es problemlos möglich, entsprechende Templates für die Einstellungen der jeweiligen IDEs zur Verfügung zu stellen. Auch sollte die Überprüfung der Coding Conventions beim Review kontrolliert werden.

Daneben können die entsprechenden Coding Conventions auch per Software überprüft und z. B. das Pushen in ein entferntes Git-Repository nur erlaubt werden, wenn die Coding Conventions eingehalten wurden. Allerdings sollte auch nicht versucht werden, soziale Probleme, welche sich bei der Einführung der Konventionen ergeben, durch rein technische Ansätze zu lösen.

Umstellung

Eine weitere Frage ist die Umstellung der bestehenden Projekte auf neue Coding Conventions. Bestimmte Dinge wie die Formatierung des Quelltextes können meist automatisch auch für größere Projekte bewerkstelligt werden.

Daneben sollte bestehender Code Stück für Stück auf die Konventionen angepasst werden, z. B. bezüglich der Benamung. Dies kann immer dann geschehen, wenn an einer entsprechenden Stelle im Rahmen einer Anforderung gearbeitet wird.

Probleme

Natürlich kann es bei der Nutzung und Einführung von Coding Conventions Probleme geben. Dies kann sich in Widerstand aus der Entwicklerschaft oder in Problemen mit der technischen Seite wie unterschiedlicher IDEs ausdrücken.

Vor allem bei einer Neueinführung kann es schwierig sein, sich an entsprechende Konventionen und Regeln zu gewöhnen, wenn vorher ohne gearbeitet wurde. Das Gleiche gilt, wenn eine Konvention nicht den eigenen Präferenzen entspricht.

Es kann passieren, dass einige Zeit dafür aufgebracht werden muss, die Konventionen zu verinnerlichen und umzusetzen. Deshalb ist es wichtig, die Konventionen klar zu kommunizieren, ihre Nutzung verpflichtend zu machen und dies im Entwicklungsprozess wie beim Review auch zu beachten.

Fazit

Coding Conventions sind ein wesentlicher Bestandteil der Softwareentwicklung und bieten viele Vorteile. Sie helfen dabei, Quelltexte einfacher lesbar, verständlich und wiederverwendbar zu machen. Dadurch wird die Wartbarkeit verbessert und die Qualität der Software erhöht. Dies kann zu einer höheren Produktivität und einem schnelleren Entwicklungsprozess führen.

Dieser Artikel erschien ursprünglich auf Golem.de und ist hier in einer alternativen Variante zu finden.

Design Pattern für JavaScript

In JavaScript kann man vernünftig programmieren, wenn man die schlechten Teile weglässt. Nicht umsonst gibt es das Buch JavaScript: The Good Parts. Dabei haben sich im Laufe der Zeit einige „Best Practices“ entwickelt, welche unter anderem in Form von Design Patterns vorliegen. Auf der Webseite http://shichuan.github.com/javascript-patterns/ kann man sich diese anschauen und so sehen, was man in Zukunft besser machen kann. Das entsprechende GitHub Projekt ist dabei unter https://github.com/shichuan/javascript-patterns/ zu finden. Leider scheint es keine definierte Lizenz für das Projekt zu geben, so das der Lizenzstatus im Moment augenscheinlich noch ungeklärt ist.