15 Jahre Erfahrung FreeCall 0800 tutegos

Bedingte Ausdrücke vereinfachen (Simplifying Conditional Expressions)

Zerlege Bedingung (Decompose Conditional)

Es gibt einen komplizierten Ausdruck in einer Fallunterscheidung.

Fasse die Bedingung in einer Methode zusammen.

if (date.before (SUMMER_START) || date.after(SUMMER_END))
  charge = quantity * _winterRate + _winterServiceCharge;
else charge = quantity * _summerRate;
[ARROW]
if (notSummer(date))
  charge = winterCharge(quantity);
else charge = summerCharge (quantity);

Für mehr Informationen siehe Seite 238 von Refactoring.

Bedingungen von Ausdrücken zusammenführen (Consolidate Conditional Expression)

Es gibt eine Reihe von Tests, die zum gleichen Ergebnis  führen.

Fasse sie zu einer einzigen Bedindung zusammen und extrahiere das zu einer Methode.

double disabilityAmount() {
if (_seniority < 2) return 0;
if (_monthsDisabled > 12) return 0;
if (_isPartTime) return 0;
// compute the disability amount
[ARROW]
double disabilityAmount() {
if (isNotEligableForDisability()) return 0;
// compute the disability amount

Mehr Informationen auf Seite 240 von Refactoring.

Wiederholte Anweisungen aus Bedingungen zusammenführen (Consolidate Duplicate Conditional Fragments)

Das gleiche Codefragment taucht in allen Zweigen einer Fallunterscheidung auf.

Lege den gemeinsamen Teil nach außen.

if (isSpecialDeal()) {
  total = price * 0.95;
  send();
}
else {
  total = price * 0.98;
  send();
}
[ARROW]
if (isSpecialDeal())
  total = price * 0.95;
else
  total = price * 0.98;
send();

Für mehr Informationen siehe Seite 243 von Refactoring

Weitere Kommentare

Im Fall von try/catch Blöcken: Im Fall von Ausnahmen kommentiert Paul Haahr, das wiederholter Code nur dann in den finally Block gesetzt werden kann, wenn alle nicht-fatalen Ausnahmen aufgefangen werden. Der finally-Block wird in jedem Fall abgearbeitet, auch wenn Fehler auftauchen, die im catch nicht abgefangen wurden. Mitwirkender: Paul Haahr.

Kontroll-Flags entfernen (Remove Control Flag)

Eine Variable steht für ein Kontroll-Flag, was den Ausstieg aus einer Schleife steuert.

Nutze ein break oder return stattdessen.

Für mehr Informationen siehe Seite 245 in Refactoring.

Geschachtelte Bedingungen durch Wächter ersetzen

Eine Methode zeigt abhängiges Verhalten, welches unklar werden lässt, was der normale Pfad der Ausführung ist.

Ersetze geschachtelte Bedingungen durch Wächter

double getPayAmount() {
  double result;
  if (_isDead) result = deadAmount();
  else {
    if (_isSeparated) result = separatedAmount();
    else {
      if (_isRetired) result = retiredAmount();
      else result = normalPayAmount();
    };
  }
  return result;
};  
[ARROW]
double getPayAmount() {
  if (_isDead) return deadAmount();
  if (_isSeparated) return separatedAmount();
  if (_isRetired) return retiredAmount();
  return normalPayAmount();
}; 

Mehr Informationen auf Seite 250 in Refactoring.

Ersetze Fallunterscheidungen durch Polymorphie (Replace Conditional with Polymorphism)

Eine Fallunterscheidung führt abhängig vom Typ eines Objektes unterschiedliches Verhalten aus.

Lege jeden Zweig der Fallunterscheidung in eine Methode einer Unterklasse. Die Methode der Oberklasse wird abstrakt und die neuen Methoden überschreiben die abstrakte Methode.

double getSpeed() {
  switch (_type) {
    case EUROPEAN:
      return getBaseSpeed();
    case AFRICAN:
      return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
    case NORWEIGIAN_BLUE:
      return (_isNailed) ? 0 : getBaseSpeed(_voltage);
  }
  throw new RuntimeException ("Should be unreachable");
}
[ARROW]
[UML]

Für weitere Informationen siehe Seite 255 in Refactoring.

Null-Objekt einführen (Introduce Null Object)

Es gibt wiederholte Abfragen auf null.

Ersetze den null-Wert mit ein null-Objekt.

if (customer == null) plan = BillingPlan.basic();
else plan = customer.getPlan();
[ARROW]
[UML]

Für mehr Informationen siehe Seite 260 in Refactoring.

Assertions einführen (Introduce Assertion)

Ein Programmteil macht Annahmen über den Status des Programms.

Die Annahmen werden ausdrücklich über eine Zusicherung (Assertion) realisiert.

double getExpenseLimit() {
  // should have either expense limit or a primary project
  return (_expenseLimit != NULL_EXPENSE) ?
    _expenseLimit:
    _primaryProject.getMemberExpenseLimit();
}
[ARROW]
double getExpenseLimit() {
Assert.isTrue (_expenseLimit != NULL_EXPENSE || _primaryProject != null);
return (_expenseLimit != NULL_EXPENSE) ?
  _expenseLimit:
  _primaryProject.getMemberExpenseLimit();
}

Mehr Informationen auf Seite 267 in Refactoring.