Haben Sie schon einmal einen Basketball- oder Fußballspieler gesehen, dessen Spiel so einfach und zugleich effektiv wirkt, dass Sie sich fragen: Warum kann nicht jeder so spielen? Er scheint nur einfache Techniken einzusetzen.
Als C++-Programmierer hatte ich denselben Gedanken beim Erkunden von John Carmacks Quellcode: Der Code ist so einfach, dass man sich fragt, warum wir Software nicht genauso schreiben können.
Sehen wir uns einige Designentscheidungen im Doom-3-Quellcode an und versuchen wir zu verstehen, warum dieser trotz seiner Einfachheit sehr effizient ist.
Am 23. November 2011 setzte id Software seine Tradition fort und veröffentlichte den Quellcode der vorherigen Engine. Viele Entwickler analysierten diesen Quellcode. Hier ein Beispiel für Feedback zu Doom 3 von Fabien Sanglard (Originalquelle):
Doom 3 BFG ist in C++ geschrieben, einer so umfangreichen Sprache, dass sich damit großartiger Code, aber auch schreckliche Konstruktionen erzeugen lassen. Glücklicherweise beschränkte sich id Software auf eine C++-Teilmenge nahe an „C mit Klassen“, die sich sehr leicht nachvollziehen lässt:
- Keine Exceptions.
- Keine Referenzen (Pointer verwenden).
- Minimale Verwendung von Templates.
- Const überall.
- Klassen.
- Polymorphie.
- Vererbung.
Zusammengefasst wird nur eine Teilmenge des C++98-Standards verwendet. Hier einige Designentscheidungen von Doom 3:
1. Eine gemeinsame Basisklasse mit nützlichen Diensten bereitstellen.
Viele Klassen erben von idClass:

idClass stellt folgende Dienste bereit:
- Instanzerzeugung.
- Verwaltung von Typinformationen.
- Event-Verwaltung.

2. String-Manipulation vereinfachen
Strings gehören in Projekten meist zu den am häufigsten verwendeten Typen. Viele Operationen arbeiten mit Strings, daher benötigen wir geeignete Funktionen zu ihrer Bearbeitung.
Doom 3 definiert die Klasse idStr, die nahezu alle nützlichen Methoden zur String-Manipulation enthält. Eigene Hilfsmethoden, wie sie bei vielen String-Klassen anderer Frameworks nötig sind, werden dadurch überflüssig.
3. Der Quellcode ist stark vom GUI-Framework (MFC) entkoppelt
In vielen MFC-Projekten ist der Code stark an dessen Typen gekoppelt, sodass MFC-Typen überall in der Codebasis auftauchen.
In Doom 3 ist der Code stark von MFC entkoppelt. Nur GUI-Klassen besitzen eine direkte Abhängigkeit, wie die folgende CQLinq-Abfrage zeigt:

Diese Entscheidung wirkt sich deutlich auf die Produktivität aus: Nur GUI-Entwickler müssen sich mit MFC beschäftigen; alle anderen verlieren keine Zeit damit.
4. Eine sehr gute Utility-Bibliothek (idlib) bereitstellen
In fast allen Projekten gehören Utility-Klassen zu den meistverwendeten Typen, wie das Ergebnis der folgenden Abfrage zeigt:

Wie zu sehen ist, werden Utility-Klassen am häufigsten genutzt. Ohne ein gutes Utility-Framework verbringen C++-Entwickler möglicherweise einen großen Teil ihrer Zeit mit technischen Details.
idlib stellt nützliche Klassen mit allen erforderlichen Methoden für Strings, Container und Speicher bereit. Das erleichtert die Arbeit und ermöglicht den Entwicklern, sich stärker auf die Spiellogik zu konzentrieren.
5. Die Implementierung ist sehr leicht verständlich
Doom 3 implementiert einen fest eingebauten Compiler. Wie C++-Entwickler wissen, ist die Entwicklung von Parsern und Compilern keine leichte Aufgabe. Dennoch ist die Doom-3-Implementierung sehr leicht verständlich und der Code ausgesprochen sauber.
Hier ist der Abhängigkeitsgraph der vom Compiler verwendeten Klassen:

Und hier ein Codeausschnitt aus dem Compiler-Quellcode:

Wir haben bereits den Quellcode vieler Parser und Compiler untersucht, doch zum ersten Mal begegnet uns ein Compiler, dessen Quellcode so leicht verständlich ist. Das gilt für den gesamten Doom-3-Quellcode. Es wirkt fast magisch – beim Erkunden kann man kaum anders als zu sagen: WOW, das ist schön!
Zusammengefasst ist der Doom-3-Quellcode sehr sauber, leicht verständlich und gut wartbar. Er verwendet nur eine Teilmenge des Standards, verzichtet auf fortgeschrittene Techniken und folgt grundlegenden Best Practices für Design, Benennung und Formatierung.
Man kann sagen, dass John Carmacks Geheimnis das KISS-Prinzip war, wie es in Wikipedia definiert wird:
KISS is an acronym for "Keep it simple, stupid" as a design principle noted by the U.S. Navy in 1960.[1][2] The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore simplicity should be a key goal in design and unnecessary complexity should be avoided. The phrase has been associated with aircraft engineer Kelly Johnson (1910–1990).[3] The term "KISS principle" was in popular use by 1970.[4] Variations on the phrase include: "Keep it simple, silly", "keep it short and simple", "keep it simple and straightforward",[5] "keep it small and simple" and "keep it stupid, simple".[6]Interessant an dieser Definition ist folgende Aussage:
Das KISS-Prinzip besagt, dass die meisten Systeme am besten funktionieren, wenn sie einfach gehalten statt unnötig kompliziert werden.Welche Lehren sollten wir bei der Einführung neuer C++-Standards ziehen?
Die neuen Standards haben viele interessante Features eingeführt. Es wäre jedoch falsch anzunehmen, dass deren vollständige Nutzung den Code automatisch effizienter macht. Viele neue Features sind vor allem für die Entwicklung generischer Bibliotheken nützlich, insbesondere jene rund um generische Programmierung.
Zwingen Sie sich nicht dazu, alle neuen Features zu verwenden. Nutzen Sie ein Feature nur dann, wenn es wirklich benötigt wird und den Code besser oder effizienter macht. Dieser interessante Beitrag beschreibt beispielsweise die Nachteile einer übermäßigen Verwendung des Schlüsselworts auto.
