Refactoring bedingter Logik
Grundlegende Refactoring-Strategien
1. Vereinfachung bedingter Ausdrücke
// Vor dem Refactoring
bool isValidUser(User* user) {
if (user != nullptr) {
if (user->isActive()) {
if (user->hasPermission()) {
return true;
}
}
}
return false;
}
// Nach dem Refactoring
bool isValidUser(User* user) {
return user && user->isActive() && user->hasPermission();
}
Refactoring-Techniken
Early-Return-Muster
// Komplexe verschachtelte Bedingungen
int processTransaction(Transaction* tx) {
if (tx == nullptr) {
return ERROR_NULL_TRANSACTION;
}
if (!tx->isValid()) {
return ERROR_INVALID_TRANSACTION;
}
if (tx->getAmount() <= 0) {
return ERROR_INVALID_AMOUNT;
}
// Verarbeitung der erfolgreichen Transaktion
return processSuccessfulTransaction(tx);
}
Methoden zur Bedingungsreduktion
Technik |
Beschreibung |
Beispiel |
Kurzschluss-Auswertung |
Logische Operatoren verwenden, um Prüfungen zu reduzieren |
if (ptr && ptr->method()) |
Ternärer Operator |
Vereinfachung einfacher bedingter Zuweisungen |
result = (condition) ? value1 : value2 |
Lookup-Tabellen |
Ersetzen komplexer Bedingungen durch Zuordnungen |
std::map<int, Action> |
Mermaid-Flowchart: Refactoring-Prozess
graph TD
A[Komplexe Bedingungen identifizieren] --> B{Mehrere verschachtelte Bedingungen?}
B --> |Ja| C[Early Return anwenden]
B --> |Nein| D[Logische Ausdrücke vereinfachen]
C --> E[Verschachtelung reduzieren]
D --> F[Logische Operatoren verwenden]
E --> G[Lesbarkeit verbessern]
F --> G
Erweiterte Refactoring-Techniken
Implementierung des State-Patterns
class UserState {
public:
virtual bool canPerformAction() = 0;
};
class ActiveUserState : public UserState {
public:
bool canPerformAction() override {
return true;
}
};
class BlockedUserState : public UserState {
public:
bool canPerformAction() override {
return false;
}
};
- Reduzierung der rechnerischen Komplexität
- Minimierung von Verzweigungen
- Verbesserung der Codewartbarkeit
- Steigerung der Lesbarkeit in LabEx-Entwicklungsumgebungen
Häufige Refactoring-Fallen
- Übermäßige Komplexität der Lösungen
- Verlust der ursprünglichen Absicht
- Erstellung unnötiger Abstraktionen
- Ignorieren von Performance-Implikationen
Praktisches Optimierungsbeispiel
// Komplexe bedingte Logik
double calculateDiscount(Customer* customer, double amount) {
double discount = 0.0;
if (customer->isPreferred()) {
if (amount > 1000) {
discount = 0.15;
} else if (amount > 500) {
discount = 0.10;
}
}
return amount * (1 - discount);
}
// Refaktorierte Version
double calculateDiscount(Customer* customer, double amount) {
static const std::map<double, double> discountTiers = {
{1000, 0.15},
{500, 0.10}
};
if (!customer->isPreferred()) return amount;
for (const auto& [threshold, rate] : discountTiers) {
if (amount > threshold) return amount * (1 - rate);
}
return amount;
}
Wichtige Erkenntnisse
- Klarheit des Codes priorisieren
- Logische Operatoren effektiv verwenden
- Designmuster bei Bedarf implementieren
- Code-Struktur kontinuierlich refaktorieren und verbessern