Wenn Sie in einem Team arbeiten und ein Programmierer Ihnen eine Schnittstelle mit Erstellungs-, Lese-, Aktualisierungs- und Löschmethoden gibt, wie vermeiden Sie dann Typwechsel?
Quoting Clean Code A Handbook of Agile Software Craftsmanship:
public Money calculatePay(Employee e)
throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calculateCommissionedPay(e);
case HOURLY:
return calculateHourlyPay(e);
case SALARIED:
return calculateSalariedPay(e);
default:
throw new InvalidEmployeeType(e.type);
}
}
Es gibt mehrere Probleme mit dieser Funktion. Erstens ist sie sehr umfangreich, und wenn neue Mitarbeitertypen hinzugefügt werden, wird sie wachsen. Zweitens macht sie ganz klar mehr als eine Sache. Drittens verstößt sie gegen den Grundsatz der einzigen Verantwortung7 (SRP), da es mehr als einen Grund für eine Änderung gibt. Viertens verstößt sie gegen das Open-Closed-Prinzip8 (OCP), weil sie sich ändern muss, wenn neue Typen hinzugefügt werden. Aber das schlimmste Problem bei dieser Funktion ist, dass es eine unbegrenzte Anzahl anderer Funktionen gibt, die die gleiche Struktur haben. Wir könnten zum Beispiel haben
isPayday(Employee e, Date date),
o
deliverPay(Employee e, Money pay),
oder eine Vielzahl anderer. Sie alle hätten die gleiche schädliche Struktur.
Das Buch sagt mir, dass ich das Factory Pattern verwenden soll, aber in einer Weise, die mir das Gefühl gibt, dass ich es nicht wirklich verwenden sollte.
Ich zitiere noch einmal das Buch:
Die Lösung für dieses Problem (siehe Listing 3-5) besteht darin, die switch-Anweisung in den Keller einer ABSTRACT FACTORY9 zu vergraben und sie niemanden sehen zu lassen.
Ist die Switch-Anweisung hässlich?