True oder False – was kann da schon schiefgehen?Rohane Hamilton | shutterstock.com Boolesche Werte wirken trügerisch einfach. Nutzt man sie dann jedoch tatsächlich einmal, kann man sich schnell in einem weitläufigen Minenfeld wiederfinden. Verstehen Sie mich nicht falsch: Ich verstehe den Reiz, den Booleans entfalten – schließlich bin ich alt genug, um mich noch an die Zeiten zu erinnern, als es noch keine Booleschen Typen gab. Die mussten wir damals mit Integers simulieren. Etwa so: 10 LET FLAG = 0 20 IF FLAG = 1 THEN PRINT “YOU WILL NEVER SEE THIS” 30 LET FLAG = 1 40 IF FLAG = 1 THEN PRINT “NOW IT PRINTS” 50 END Im Vergleich dazu sind Booleans performant und simpel. Dennoch kann ich auf der Grundlage meiner jahrelangen Erfahrung als Entwickler nur empfehlen, sie nach Möglichkeit zu vermeiden. Und wenn das nicht möglich ist, sie äußerst vorsichtig und mit Bedacht einzusetzen. Natürlich gibt es auch Ausnahmen, beziehungsweise einfache Fälle wie isLoading, bei denen nur True oder False möglich ist. Von diesen Fällen abgesehen, können Entwickler mit Booleans jedoch leicht in eine Falle tappen – und am Ende komplizierten, schwer verständlichen Code produzieren. Um das zu verhindern, kann ich Ihnen die folgenden fünf Regeln ans Herz legen, an denen ich mich auch selbst stets orientiere. 1. Positiv bleiben Wenn ich es mit Booleschen Variablen zu tun bekomme, versuche ich, deren Namen stets positiv zu halten. Variablen, die True “sind”, gewährleisten, dass Dinge funktionieren und passieren. Deshalb bevorzuge ich Ausdrücke wie: if UserIsAuthorized { // Do something } Statt: if !UserIsNotAuthorized { // Do something } Ersterer Code ist wesentlich leichter lesbar und besser zu verstehen. Schließlich sind doppelte Verneinungen deutlich anstrengender für den menschlichen Denkapparat. 2. Positive-First-Ansatz durchziehen In diesem Sinne empfiehlt es sich auch, bei if…else-Konstruktionen die positive Klausel stets an erste Stelle zu setzen. Verzichten Sie also auf Vorgehensweisen wie: if not Authorized { // bad stuff } else { // good stuff } Und setzen Sie stattdessen auf: if Authorized { // Things are okay } else { // Go away!! } Das ist leichter zu lesen und erspart Ihrem Gehirn außerdem, not verarbeiten zu müssen. 3. Komplexe Ausdrücke vermeiden Erklärende Variablen werden unterschätzt und verkannt – in erster Linie, weil Developer schnell vorankommen wollen. Es lohnt sich allerdings fast immer, über den eigenen Code auch zu reflektieren. Ich für meinen Teil nutze zwischen benannten Variablen ausschließlich && und || – niemals Raw Expressions. Aber mir begegnen ständig Code-Schnipsel dieser Art: if (user.age > 18 && user.isActive && !user.isBanned && user.subscriptionLevel >= 2) { grantAccess(); } Denken Sie an den armen Tropf, der dieses Monstrum lesen – und dann wie folgt umschreiben muss: const isAdult = user.age > 18; const hasAccess = !user.isBanned; const isActive = user.isActive; const isSubscriber = user.subscriptionLevel >= 2; const canAccess = isAdult && hasAccess && isActive && isSubscriber; if (canAccess) { grantAccess(); } So ist das Ganze lesbar und transparent. Dabei sollten Sie sich nicht scheuen, erklärende Variablen klar herauszustellen. Die Wahrscheinlichkeit, dass sich jemand über Code wie den folgenden beschwert, ist eher gering: const userHasJumpedThroughAllTheRequiredHoops = true; Klar, das bedeutet mehr Tipparbeit, allerdings sollte Klarheit und Transparenz wichtiger sein, als ein paar Tastenanschläge zu sparen. Dazu kommt, dass sich erklärende Variablen hervorragend für Unit-Tests eignen und auch Logging und Debugging erheblich vereinfachen. 4. Auf Boolesche Parameter verzichten Kaum etwas generiert wohl pro Minute mehr “WTF?“-Kommentare als Boolesche Parameter. Vergegenwärtigen Sie sich beispielsweise folgendes “Juwel”: saveUser(user, true, false); // …the heck does this even mean? Wenn Sie diese Funktion schreiben, sieht erst einmal alles gut aus, weil die Parameter benannt sind. Geht es jedoch darum, die Funktion aufzurufen, muss ein Maintainer erst einmal die Funktionsdeklaration suchen, um zu verstehen, was hier übergeben wird. Ein besserer Weg: Vermeiden Sie Booleans einfach komplett und deklarieren Sie einen deskriptiven enum-Typ für die Parameter, der darüber Auskunft gibt, was vor sich geht: enum WelcomeEmailOption { Send, DoNotSend, } enum VerificationStatus { Verified, Unverified, } Ihre Funktion könnte dann wie folgt aussehen: function saveUser( user: User, emailOption: WelcomeEmailOption, verificationStatus: VerificationStatus ): void { if (emailOption === WelcomeEmailOption.Send) { sendEmail(user.email, ‘Welcome!’); } if (verificationStatus === VerificationStatus.Verified) { user.verified = true; } // save user to database… } Und so könnten Sie diese aufrufen: saveUser(newUser, WelcomeEmailOption.Send, VerificationStatus.Unverified); Eine Wohltat für jedes Dev-Gehirn, liest sich dieser Call wie eine Dokumentation: Klar, prägnant – und der Maintainer kann unmittelbar erkennen, was der Aufruf bewirkt und die Parameter bedeuten. 5. Vorausschauend programmieren Ein Vorteil von enums: Sie sind erweiterbar. Angenommen, Sie programmieren ein System für Lebensmittel, das auch große und kleine Getränke umfasst. Das könnte in folgendem Code resultieren: var IsSmallDrink: boolean; Anschließend bauen Sie Ihr System um diese Boolesche Variable herum auf und legen sogar Boolesche Felder in der Datenbank dafür an. Nur um dann in der nächsten Kaffeepause dem Chef in die Arme zu laufen, der Sie kurz angebunden darüber informiert, dass künftig auch mittelgroße Getränke zum Sortiment gehören. Und schon wird eine simple Boolesche Variable zu einem eklatanten Problem. Um Situationen wie diese gar nicht erst aufkommen zu lassen, vermeiden Sie Boolesche Variablen. Etwa damit: enum DrinkSize { Small, Large } Dieser Code macht es bedeutend leichter, die neue Getränkegröße hinzuzufügen. (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
5 Boolean-Tipps für Entwickler
True oder False – was kann da schon schiefgehen?Rohane Hamilton | shutterstock.com Boolesche Werte wirken trügerisch einfach. Nutzt man sie dann jedoch tatsächlich einmal, kann man sich schnell in einem weitläufigen Minenfeld wiederfinden. Verstehen Sie mich nicht falsch: Ich verstehe den Reiz, den Booleans entfalten – schließlich bin ich alt genug, um mich noch an die Zeiten zu erinnern, als es noch keine Booleschen Typen gab. Die mussten wir damals mit Integers simulieren. Etwa so: 10 LET FLAG = 0 20 IF FLAG = 1 THEN PRINT "YOU WILL NEVER SEE THIS" 30 LET FLAG = 1 40 IF FLAG = 1 THEN PRINT "NOW IT PRINTS" 50 END Im Vergleich dazu sind Booleans performant und simpel. Dennoch kann ich auf der Grundlage meiner jahrelangen Erfahrung als Entwickler nur empfehlen, sie nach Möglichkeit zu vermeiden. Und wenn das nicht möglich ist, sie äußerst vorsichtig und mit Bedacht einzusetzen. Natürlich gibt es auch Ausnahmen, beziehungsweise einfache Fälle wie isLoading, bei denen nur True oder False möglich ist. Von diesen Fällen abgesehen, können Entwickler mit Booleans jedoch leicht in eine Falle tappen – und am Ende komplizierten, schwer verständlichen Code produzieren. Um das zu verhindern, kann ich Ihnen die folgenden fünf Regeln ans Herz legen, an denen ich mich auch selbst stets orientiere. 1. Positiv bleiben Wenn ich es mit Booleschen Variablen zu tun bekomme, versuche ich, deren Namen stets positiv zu halten. Variablen, die True “sind”, gewährleisten, dass Dinge funktionieren und passieren. Deshalb bevorzuge ich Ausdrücke wie: if UserIsAuthorized { // Do something } Statt: if !UserIsNotAuthorized { // Do something } Ersterer Code ist wesentlich leichter lesbar und besser zu verstehen. Schließlich sind doppelte Verneinungen deutlich anstrengender für den menschlichen Denkapparat. 2. Positive-First-Ansatz durchziehen In diesem Sinne empfiehlt es sich auch, bei if...else-Konstruktionen die positive Klausel stets an erste Stelle zu setzen. Verzichten Sie also auf Vorgehensweisen wie: if not Authorized { // bad stuff } else { // good stuff } Und setzen Sie stattdessen auf: if Authorized { // Things are okay } else { // Go away!! } Das ist leichter zu lesen und erspart Ihrem Gehirn außerdem, not verarbeiten zu müssen. 3. Komplexe Ausdrücke vermeiden Erklärende Variablen werden unterschätzt und verkannt – in erster Linie, weil Developer schnell vorankommen wollen. Es lohnt sich allerdings fast immer, über den eigenen Code auch zu reflektieren. Ich für meinen Teil nutze zwischen benannten Variablen ausschließlich && und || – niemals Raw Expressions. Aber mir begegnen ständig Code-Schnipsel dieser Art: if (user.age > 18 && user.isActive && !user.isBanned && user.subscriptionLevel >= 2) { grantAccess(); } Denken Sie an den armen Tropf, der dieses Monstrum lesen – und dann wie folgt umschreiben muss: const isAdult = user.age > 18; const hasAccess = !user.isBanned; const isActive = user.isActive; const isSubscriber = user.subscriptionLevel >= 2; const canAccess = isAdult && hasAccess && isActive && isSubscriber; if (canAccess) { grantAccess(); } So ist das Ganze lesbar und transparent. Dabei sollten Sie sich nicht scheuen, erklärende Variablen klar herauszustellen. Die Wahrscheinlichkeit, dass sich jemand über Code wie den folgenden beschwert, ist eher gering: const userHasJumpedThroughAllTheRequiredHoops = true; Klar, das bedeutet mehr Tipparbeit, allerdings sollte Klarheit und Transparenz wichtiger sein, als ein paar Tastenanschläge zu sparen. Dazu kommt, dass sich erklärende Variablen hervorragend für Unit-Tests eignen und auch Logging und Debugging erheblich vereinfachen. 4. Auf Boolesche Parameter verzichten Kaum etwas generiert wohl pro Minute mehr “WTF?“-Kommentare als Boolesche Parameter. Vergegenwärtigen Sie sich beispielsweise folgendes “Juwel”: saveUser(user, true, false); // ...the heck does this even mean? Wenn Sie diese Funktion schreiben, sieht erst einmal alles gut aus, weil die Parameter benannt sind. Geht es jedoch darum, die Funktion aufzurufen, muss ein Maintainer erst einmal die Funktionsdeklaration suchen, um zu verstehen, was hier übergeben wird. Ein besserer Weg: Vermeiden Sie Booleans einfach komplett und deklarieren Sie einen deskriptiven enum-Typ für die Parameter, der darüber Auskunft gibt, was vor sich geht: enum WelcomeEmailOption { Send, DoNotSend, } enum VerificationStatus { Verified, Unverified, } Ihre Funktion könnte dann wie folgt aussehen: function saveUser( user: User, emailOption: WelcomeEmailOption, verificationStatus: VerificationStatus ): void { if (emailOption === WelcomeEmailOption.Send) { sendEmail(user.email, 'Welcome!'); } if (verificationStatus === VerificationStatus.Verified) { user.verified = true; } // save user to database... } Und so könnten Sie diese aufrufen: saveUser(newUser, WelcomeEmailOption.Send, VerificationStatus.Unverified); Eine Wohltat für jedes Dev-Gehirn, liest sich dieser Call wie eine Dokumentation: Klar, prägnant – und der Maintainer kann unmittelbar erkennen, was der Aufruf bewirkt und die Parameter bedeuten. 5. Vorausschauend programmieren Ein Vorteil von enums: Sie sind erweiterbar. Angenommen, Sie programmieren ein System für Lebensmittel, das auch große und kleine Getränke umfasst. Das könnte in folgendem Code resultieren: var IsSmallDrink: boolean; Anschließend bauen Sie Ihr System um diese Boolesche Variable herum auf und legen sogar Boolesche Felder in der Datenbank dafür an. Nur um dann in der nächsten Kaffeepause dem Chef in die Arme zu laufen, der Sie kurz angebunden darüber informiert, dass künftig auch mittelgroße Getränke zum Sortiment gehören. Und schon wird eine simple Boolesche Variable zu einem eklatanten Problem. Um Situationen wie diese gar nicht erst aufkommen zu lassen, vermeiden Sie Boolesche Variablen. Etwa damit: enum DrinkSize { Small, Large } Dieser Code macht es bedeutend leichter, die neue Getränkegröße hinzuzufügen. (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
5 Boolean-Tipps für Entwickler True oder False – was kann da schon schiefgehen?Rohane Hamilton | shutterstock.com Boolesche Werte wirken trügerisch einfach. Nutzt man sie dann jedoch tatsächlich einmal, kann man sich schnell in einem weitläufigen Minenfeld wiederfinden. Verstehen Sie mich nicht falsch: Ich verstehe den Reiz, den Booleans entfalten – schließlich bin ich alt genug, um mich noch an die Zeiten zu erinnern, als es noch keine Booleschen Typen gab. Die mussten wir damals mit Integers simulieren. Etwa so: 10 LET FLAG = 0 20 IF FLAG = 1 THEN PRINT "YOU WILL NEVER SEE THIS" 30 LET FLAG = 1 40 IF FLAG = 1 THEN PRINT "NOW IT PRINTS" 50 END Im Vergleich dazu sind Booleans performant und simpel. Dennoch kann ich auf der Grundlage meiner jahrelangen Erfahrung als Entwickler nur empfehlen, sie nach Möglichkeit zu vermeiden. Und wenn das nicht möglich ist, sie äußerst vorsichtig und mit Bedacht einzusetzen. Natürlich gibt es auch Ausnahmen, beziehungsweise einfache Fälle wie isLoading, bei denen nur True oder False möglich ist. Von diesen Fällen abgesehen, können Entwickler mit Booleans jedoch leicht in eine Falle tappen – und am Ende komplizierten, schwer verständlichen Code produzieren. Um das zu verhindern, kann ich Ihnen die folgenden fünf Regeln ans Herz legen, an denen ich mich auch selbst stets orientiere. 1. Positiv bleiben Wenn ich es mit Booleschen Variablen zu tun bekomme, versuche ich, deren Namen stets positiv zu halten. Variablen, die True “sind”, gewährleisten, dass Dinge funktionieren und passieren. Deshalb bevorzuge ich Ausdrücke wie: if UserIsAuthorized { // Do something } Statt: if !UserIsNotAuthorized { // Do something } Ersterer Code ist wesentlich leichter lesbar und besser zu verstehen. Schließlich sind doppelte Verneinungen deutlich anstrengender für den menschlichen Denkapparat. 2. Positive-First-Ansatz durchziehen In diesem Sinne empfiehlt es sich auch, bei if...else-Konstruktionen die positive Klausel stets an erste Stelle zu setzen. Verzichten Sie also auf Vorgehensweisen wie: if not Authorized { // bad stuff } else { // good stuff } Und setzen Sie stattdessen auf: if Authorized { // Things are okay } else { // Go away!! } Das ist leichter zu lesen und erspart Ihrem Gehirn außerdem, not verarbeiten zu müssen. 3. Komplexe Ausdrücke vermeiden Erklärende Variablen werden unterschätzt und verkannt – in erster Linie, weil Developer schnell vorankommen wollen. Es lohnt sich allerdings fast immer, über den eigenen Code auch zu reflektieren. Ich für meinen Teil nutze zwischen benannten Variablen ausschließlich && und || – niemals Raw Expressions. Aber mir begegnen ständig Code-Schnipsel dieser Art: if (user.age > 18 && user.isActive && !user.isBanned && user.subscriptionLevel >= 2) { grantAccess(); } Denken Sie an den armen Tropf, der dieses Monstrum lesen – und dann wie folgt umschreiben muss: const isAdult = user.age > 18; const hasAccess = !user.isBanned; const isActive = user.isActive; const isSubscriber = user.subscriptionLevel >= 2; const canAccess = isAdult && hasAccess && isActive && isSubscriber; if (canAccess) { grantAccess(); } So ist das Ganze lesbar und transparent. Dabei sollten Sie sich nicht scheuen, erklärende Variablen klar herauszustellen. Die Wahrscheinlichkeit, dass sich jemand über Code wie den folgenden beschwert, ist eher gering: const userHasJumpedThroughAllTheRequiredHoops = true; Klar, das bedeutet mehr Tipparbeit, allerdings sollte Klarheit und Transparenz wichtiger sein, als ein paar Tastenanschläge zu sparen. Dazu kommt, dass sich erklärende Variablen hervorragend für Unit-Tests eignen und auch Logging und Debugging erheblich vereinfachen. 4. Auf Boolesche Parameter verzichten Kaum etwas generiert wohl pro Minute mehr “WTF?“-Kommentare als Boolesche Parameter. Vergegenwärtigen Sie sich beispielsweise folgendes “Juwel”: saveUser(user, true, false); // ...the heck does this even mean? Wenn Sie diese Funktion schreiben, sieht erst einmal alles gut aus, weil die Parameter benannt sind. Geht es jedoch darum, die Funktion aufzurufen, muss ein Maintainer erst einmal die Funktionsdeklaration suchen, um zu verstehen, was hier übergeben wird. Ein besserer Weg: Vermeiden Sie Booleans einfach komplett und deklarieren Sie einen deskriptiven enum-Typ für die Parameter, der darüber Auskunft gibt, was vor sich geht: enum WelcomeEmailOption { Send, DoNotSend, } enum VerificationStatus { Verified, Unverified, } Ihre Funktion könnte dann wie folgt aussehen: function saveUser( user: User, emailOption: WelcomeEmailOption, verificationStatus: VerificationStatus ): void { if (emailOption === WelcomeEmailOption.Send) { sendEmail(user.email, 'Welcome!'); } if (verificationStatus === VerificationStatus.Verified) { user.verified = true; } // save user to database... } Und so könnten Sie diese aufrufen: saveUser(newUser, WelcomeEmailOption.Send, VerificationStatus.Unverified); Eine Wohltat für jedes Dev-Gehirn, liest sich dieser Call wie eine Dokumentation: Klar, prägnant – und der Maintainer kann unmittelbar erkennen, was der Aufruf bewirkt und die Parameter bedeuten. 5. Vorausschauend programmieren Ein Vorteil von enums: Sie sind erweiterbar. Angenommen, Sie programmieren ein System für Lebensmittel, das auch große und kleine Getränke umfasst. Das könnte in folgendem Code resultieren: var IsSmallDrink: boolean; Anschließend bauen Sie Ihr System um diese Boolesche Variable herum auf und legen sogar Boolesche Felder in der Datenbank dafür an. Nur um dann in der nächsten Kaffeepause dem Chef in die Arme zu laufen, der Sie kurz angebunden darüber informiert, dass künftig auch mittelgroße Getränke zum Sortiment gehören. Und schon wird eine simple Boolesche Variable zu einem eklatanten Problem. Um Situationen wie diese gar nicht erst aufkommen zu lassen, vermeiden Sie Boolesche Variablen. Etwa damit: enum DrinkSize { Small, Large } Dieser Code macht es bedeutend leichter, die neue Getränkegröße hinzuzufügen. (fm) Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!