Refactoring Conditional Logic
Fundamental Refactoring Strategies
1. Simplify Conditional Expressions
// Before refactoring
bool isValidUser(User* user) {
if (user != nullptr) {
if (user->isActive()) {
if (user->hasPermission()) {
return true;
}
}
}
return false;
}
// After refactoring
bool isValidUser(User* user) {
return user && user->isActive() && user->hasPermission();
}
Refactoring Techniques
Early Return Pattern
// Complex nested conditions
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;
}
// Process successful transaction
return processSuccessfulTransaction(tx);
}
Condition Reduction Methods
Technique |
Description |
Example |
Short-circuit Evaluation |
Use logical operators to reduce checks |
if (ptr && ptr->method()) |
Ternary Operator |
Simplify simple conditional assignments |
result = (condition) ? value1 : value2 |
Lookup Tables |
Replace complex conditionals with mappings |
std::map<int, Action> |
Mermaid Flowchart: Refactoring Process
graph TD
A[Identify Complex Conditionals] --> B{Multiple Nested Conditions?}
B --> |Yes| C[Apply Early Return]
B --> |No| D[Simplify Logical Expressions]
C --> E[Reduce Nesting]
D --> F[Use Logical Operators]
E --> G[Improve Code Readability]
F --> G
Advanced Refactoring Techniques
State Pattern Implementation
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;
}
};
- Reduce computational complexity
- Minimize branching
- Improve code maintainability
- Enhance readability in LabEx development environments
Common Refactoring Pitfalls
- Over-engineering solutions
- Losing original intent
- Creating unnecessary abstraction
- Ignoring performance implications
Practical Optimization Example
// Complex conditional logic
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);
}
// Refactored 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;
}
Key Takeaways
- Prioritize code clarity
- Use logical operators effectively
- Implement design patterns when appropriate
- Continuously refactor and improve code structure