01 · Problem
Wofür braucht man das?
Viele kleine Ja/Nein-Zustände können kompakt gespeichert und sehr schnell kombiniert werden, wenn jeder Zustand genau ein Bit besitzt.
02 · Denkmodell
Das mentale Modell
Jede erlaubte Flag ist eine Zweierpotenz. OR setzt Bits, AND mit invertierter Maske löscht Bits und AND prüft eine einzelne oder kombinierte Maske.
BitwiseFeatureFlags implementiert enable, disable und isEnabled intern, exportiert aber nichts. Erlaubte Enum-Werte werden nicht auf Zweierpotenzen geprüft und JavaScript begrenzt Number-Bitoperationen auf 32 Bit.
03 · Kontrollfluss
Was passiert in welcher Reihenfolge?
- Jeder Feature-ID genau eine Zweierpotenz zuweisen.
- Angeforderte Flags gegen eine erlaubte Menge validieren.
- Maske mit OR setzen oder mit AND-NOT löschen.
- Bei Abfrage alle angeforderten Bits vergleichen.
04 · Bauteile
Die entscheidenden Verträge
BitwiseFeatureFlags (intern)
Nicht exportierte Klasse mit einer numerischen Gesamtmaske.
enableFlag / disableFlag
Setzen oder löschen Bits nach einer Validierung.
isFlagEnabled
Prüft, ob alle Bits einer Flagmaske gesetzt sind.
05 · Build it yourself
Selbst implementieren
Validiere das Datenmodell beim Erzeugen; ungültige Flags sollten später nicht nur geloggt werden.
- Akzeptiere nur positive einzelne Zweierpotenzen als Basisflags.
- Wirf bei unbekannten Flags einen definierten Fehler.
- Nutze bigint, sobald mehr als 31 unabhängige Bits benötigt werden.
class Flags {
private mask = 0;
constructor(private allowed: ReadonlySet<number>) {}
private check(flag: number) {
if (!this.allowed.has(flag)) throw new RangeError("Unknown flag");
}
enable(flag: number) { this.check(flag); this.mask |= flag; }
disable(flag: number) { this.check(flag); this.mask &= ~flag; }
has(flag: number) { this.check(flag); return (this.mask & flag) === flag; }
value() { return this.mask; }
}06 · Verifizieren
Was du testen solltest
- Jedes erlaubte Bit lässt sich unabhängig setzen und löschen.
- Kombinierte Abfragen bestehen nur, wenn alle enthaltenen Bits gesetzt sind.
- Null, Nicht-Zweierpotenzen, unbekannte und zu große Flags werden abgelehnt.
07 · Grenzen
Kompromisse und Stolperfallen
- Number-Bitoperatoren arbeiten als signed 32-bit Integer.
- Bitmasken sind kompakt, aber ohne Symboltabelle schlecht lesbar und migrationsanfällig.
Numerische TypeScript-Enums besitzen Reverse-Mappings. Object.values enthält daher nicht automatisch nur gültige Zahlenflags.
08 · Weiterdenken