Häufig gilt es zwei Zustände abzubilden, etwas ist A oder C. Und leider wird häufig hierfür ein Boolscher-Wert verwendet, obwohl andere Varianten sehr viel besser geeignet wären.

In vielen Fällen gibt es Eigenschaften, die aktiv sind, oder nicht. Zwei Zustände. Ein Computer ist kaputt oder nicht. Der Server läuft oder nicht. Für solche Fälle sind Boolsche-Werte gut geeignet.

Aber in vielen Fällen impliziert ein nicht A etwas, das nicht direkt mit A zusammen hängt, nicht sofort ersichtlich ist, andere Interpretationen zulässt oder nur durch implizites Wissen erkannt werden kann.

Ein Beispiel wären Farben. Wenn ich zwischen den Eigenschaften “schwarz” und “weiß” unterscheiden möchte, ist von einem Leser des Kodes nicht unbedingt zu erwarten, dass “nicht weiß” automatisch “schwarz” bedeutet. Es könnte auf den ersten Blick auch Assoziationen zu “rot” oder “grün” hervorrufen. Bei solchen dualen Zuständen greife ich daher lieber zu Enumerations, um beide Werte explizit benennen zu können.
Ein color = Color.WHITE und ein color = Color.BLACK sind stets explizit als das erkennbar, was sie sind, im Gegensatz zu einem color = !Color.WHITE für den Schwarzwert.

In einem Real-Life Beispiel ging es um eine Eigenschaft eines Videostreams, der entweder ein “Livestream” (durchgehende Liveübertragung) oder ein “Loop” (ein vorbereiteter Videoausschnitt, der in Schleife wiedergegeben wird) sein konnte. Wenn man an dieser Stelle die fachlichen Anforderungen kennt (von denen es stets sehr viele gibt), kann es klar sein, dass ein Videostream eine “Loop” ist, wenn es keine “Livestream” ist. Aber neue Entwickler werden, wenn sie not livestream lesen, nicht an “Loop” denken.

Die Verwendung von Enumerations an dieser Stelle bringt auch weitere Vorteile mit sich. Zum einen kann man die Wertemenge jederzeit einfach erweitern, indem die Enumeration ergänzt wird. Zum anderen sind Methodenaufrufe mit diesem Wert als Parameter lesbarer:
An einer anderen Stelle wurde aus myMethod("myString", true, false, ...) ein
myMethod("myString", Operation.Include, Escaping.Off, ...), was bei der Zuordnung der Werte zu den Funktionen der Parameter weit hilfreicher ist.