Verwenden Sie keine Verneinung nicht!
Wenn ich es schaffe, eine if-Anweisung zu vermeiden, dann versüßt mir das immer meinen Tag. Aber leider kann man als Entwickler nicht darauf verzichten, Bedingungen in den Code einzubauen.
Was ich jedoch versuche, an allen Stellen zu vermeiden, ist der schreckliche „not”-Operator, der in den meisten Sprachen durch den Einsatz von „!” implementiert wird. Der Einsatz dieses Operators macht den Quellcode immer schwerer zu lesen. Ich möchte keine Bedingungen wie die folgende in meinem Code haben:
if (!$this->isUserAuthenticated()) {
$this->requireLogin();
}
So ein kleines Ausrufezeichen übersieht man einfach viel zu leicht und da es die Logik des Ausdrucks komplett umdreht, ist es einfach viel zu wichtig, um übersehen zu werden. Noch schlimmer wird es, wenn Sie den Operator mehrfach in einer Bedingung einsetzen.
if (!$this->isUserAuthenticated() && !$this->isInternalIP()) {
$this->requireLogin();
}
In solchen Code-Stellen kommt es gerne auch mal vor, dass man UND mit ODER verwechselt. Denn wenn man etwas negieren möchte, sollte man dran denken, auch die Verknüpfung zu negieren oder entsprechend zu klammern. Die obige Bedingung ist mit der folgenden identisch, statt einem logischen UND verwenden Sie jedoch ein logisches ODER:
if (!($this->isUserAuthenticated() || $this->isInternalIP())) {
$this->requireLogin();
}
Auf den ersten Blick erschließt sich mir nie, was die Bedingung aussagt, sobald ein „not”-Operator im Spiel ist.
Aber welche Möglichkeiten gibt es, um den ungeliebten Operator loszuwerden?
Verneinen Sie den Methodennamen
Statt einer Methode isUserAuthenticated() einen „not”-Operator voranzustellen, könnten Sie eine zweite Methode implementieren, die bereits auf das Gegenteil prüft und einen sprechenden Namen hat:
if ($this->isUserUnknown()) {
$this->requireLogin();
}
So liest sich der gesamte Code viel flüssiger und es kann nicht dazu kommen, dass der Operator übersehen wird oder das Ergebis im Kopf evaluiert werden muss.
Prüfen Sie auf false
Statt den „not”-Operator zu verwenden, können Sie die Rückgabe der Methode auf false prüfen:
if (false === $this->isUserAuthenticated()) {
$this->requireLogin();
}
Der Code ist zwar nicht so lesbar wie im vorherigen Beispiel, aber wenn Sie die Bedingung nur einmal prüfen müssen, kann es sinnvoll sein, auf die Implementierung einer Methode für diesen einen Fall zu verzichten. Achten Sie übrigens immer darauf, bei einer Bedingung den konstanten Wert auf der linken Seite der Klammer zu setzen. Sollten Sie zu wenige Gleichheitszeichen verwenden, so kann aus der Bedingung nicht aus Versehen eine Zuweisung werden.
Verwenden Sie unless
Sollten Sie Ruby verwenden, so haben Sie noch eine dritte, sehr elegante Möglichkeit. Ruby bietet Ihnen neben der if-Anweisung auch eine unless-Anweisung, die, wenn Sie sie als Modifier einsetzen, besonders elegant zu lesen ist.
require_authentication unless user_is_authenticated
In diesem Beispiel ist der Code kaum noch von einem englischen Satz zu unterscheiden. Unterstützt wird das natürlich noch dadurch, dass Sie in Ruby keine Klammern verwenden müssen, wenn Sie keine Parameter an eine Methode übergeben wollen.
Wenn Sie also das nächste Mal eine Bedingung negieren, dann denken Sie darüber nach, ob es keine bessere Lösung gibt. Und falls Sie in einer Bedingung zweimal negieren müssen, dann denken Sie nochmal über eine Alternative nach. Es gibt sie sicher.
Xing
LinkedIn
Twitter
Ohloh
Slideshare
Facebook
Delicious
Github
Technorati
Flickr
Last.fm
YouTube
Amazon Wishlist
vor 2 Jahren
Das gleiche resultat wie mit dem unless-Operator kann man auch in PHP mit einem “or” (equivalent zu “||”, nicht aber “|”) erreichen. Nur ist die reihenfolge dabei umgedreht:
user_is_authenticated() OR require_authentication();
Ist fast genauso lesbar.
vor 1 Jahr
Hallo,
alles was du hier schreibst ist soweit nachvollziehbar bis auf den Punkt mit == false. Da möchte ich dir vollkommen widersprechen. == false macht das ganze genausoviel lesbarer wie es den Code lesbarer macht in einer for Schleife die Zählvariable counter oder elementCounter zu nennen.