====== Verwenden von Wächtern =====)

Häufig werden an verschiedenen Stellen des Programms Dinge überprüft, so dass man sehr schnell in tiefe Verschachtlungen hineinkommt.

Um dem entgegenzuwirken, hat sich ein Prinzip entwickelt, bei dem man durch Verwenden von sogenannten Wächtern die Verschachtlungstiefe drastisch reduzieren kann. Der Grundgedanke dabei ist ganz einfach, er ist eigentlich nur das Umdrehen der Bedingungen. Wenn wir zum Beispiel eine bestimmte Datei brauchen um unseren Algorithmus fortzusetzen, dann würden das normalerweise so aussehen:

bool coolerAlgorithmus()
{
  if( existsFile("important.txt") )
  {
    // Nützlicher Code
  }
}

Dabei haben wir schon nur für eine einzige Überprüfung eine Einrückungsebene „verschwendet“. Und jetzt schauen wir uns im Vergleich dazu, den selben Code unter Verwendung eines Wächters an:

bool coolerAlgorithmus()
{
  if( !existsFile("important.txt") )  // Der Wächter
    return false; 
 
  // Nützlicher Code
}

Wie wir sehen können, müssen wir einfach nur unsere Abfrage umdrehen und wenn sie erfüllt ist den Algorithmus beenden. In diesem einfachen Beispiel haben wir uns noch nicht sehr viel erspart, aber bei längeren Funktionen kann man die Lesbarkeit so stark verbessern, wie wir im nächsten Beispiel leicht erkennen können:

Beispiel ohne Wächter

bool coolerAlgorithmus()
{
  if( existsFile("important.txt") )
  {
    // Irgendetwas mit der Datei machen
    if( keys > 0 )
    {
      // ... und was viel besseres mit keys machen
      if( !error )
      {
        // ... und schon wieder eine Ebene Tiefer
        if( existsFile("another.txt") )
        {
          // Wir brauchen wieder eine Datei ;)
          return true;
        }
      }
    }
  }
}

Der Algorithmus verschachtelt sich immer weiter. Das ist für den Compiler kein Problem, das Programm wird dadurch nicht langsamer, doch für den Entwickler gilt es immer mehr Besonderheiten im Hinterkopf zu behalten.

Mit Wächtern

bool coolerAlgorithmus()
{
  if( !existsFile("important.txt") ) 
    return false;
 
  // Irgendetwas mit der Datei machen
 
  if( keys <= 0 ) 
    return false;
 
  // ... und was viel besseres mit keys machen
 
  if( error ) 
    return false;
 
  // ... diesmal keine Ebene Tiefer
 
  if( !existsFile("another.txt") ) 
    return false;
 
  // Wir brauchen wieder eine Datei ;)
 
  return true;
}

Wächter funktionieren hier so, dass sie Vorabbedingungen sicherstellen, die für den nachfolgenden Code notwendig sind. Man kann sich also nach einem Wächter darauf verlassen, dass diese Bedingung gültig abgeprüft wurde. Es gibt lediglich einen Nachteil, dass Resourcen (Speicher, Dateien) explizit freigegeben müssen, wenn ein Wächter die Funktion abbricht. Ein Wächter eignet sich also besonders dann, wenn Bedingungen abgeprüft werden und im vorherigen noch nur wenige Resourcen verwendet wurden.