acc-suggest-simplification
Code Simplification Suggestions
Analyze PHP code for simplification and refactoring opportunities.
Simplification Patterns
1. Extract Method
// BEFORE: Long inline code block
public function processOrder(Order $order): void
{
// Validate order (5 lines)
if ($order->getItems()->isEmpty()) {
throw new EmptyOrderException();
}
if ($order->getTotal()->isNegative()) {
throw new InvalidTotalException();
}
// Process payment (10 lines)
$payment = $this->paymentGateway->charge(
$order->getTotal(),
$order->getPaymentMethod()
);
if (!$payment->isSuccessful()) {
throw new PaymentFailedException();
}
// Send notifications (5 lines)
$this->mailer->send($order->getCustomer()->getEmail(), 'order_confirmed');
}
// AFTER: Extracted methods
public function processOrder(Order $order): void
{
$this->validateOrder($order);
$this->processPayment($order);
$this->sendConfirmation($order);
}
private function validateOrder(Order $order): void {}
private function processPayment(Order $order): Payment {}
private function sendConfirmation(Order $order): void {}
2. Introduce Explaining Variable
// BEFORE: Complex expression
if ($user->getSubscription()?->isActive()
&& $user->getCreatedAt() < new DateTime('-30 days')
&& !$user->hasUsedTrial()
&& $user->getOrderCount() > 0) {
$this->offerUpgrade($user);
}
// AFTER: Named variables
$hasActiveSubscription = $user->getSubscription()?->isActive();
$isEstablishedUser = $user->getCreatedAt() < new DateTime('-30 days');
$eligibleForUpgrade = !$user->hasUsedTrial() && $user->getOrderCount() > 0;
if ($hasActiveSubscription && $isEstablishedUser && $eligibleForUpgrade) {
$this->offerUpgrade($user);
}
// EVEN BETTER: Extract to method
if ($user->isEligibleForUpgrade()) {
$this->offerUpgrade($user);
}
3. Remove Redundant Code
// BEFORE: Redundant checks
if ($value !== null) {
if ($value !== null) { // Duplicate check
$this->process($value);
}
}
// BEFORE: Unnecessary else
if ($condition) {
return $a;
} else {
return $b;
}
// AFTER: Simplified
if ($condition) {
return $a;
}
return $b;
// BEFORE: Redundant boolean
if ($condition === true) {}
return $value === true;
// AFTER: Simplified
if ($condition) {}
return $value;
4. Simplify Conditionals
// BEFORE: Nested conditionals
if ($user !== null) {
if ($user->isActive()) {
if ($user->hasPermission('edit')) {
return true;
}
}
}
return false;
// AFTER: Combined condition
return $user !== null
&& $user->isActive()
&& $user->hasPermission('edit');
// BEFORE: Negative condition
if (!$items->isEmpty()) {
$this->process($items);
}
// AFTER: Positive condition
if ($items->isNotEmpty()) {
$this->process($items);
}
5. Replace Temp with Query
// BEFORE: Temporary variable used once
$basePrice = $order->getBasePrice();
$discount = $basePrice * 0.1;
return $basePrice - $discount;
// AFTER: Inline or method
return $order->getBasePrice() * 0.9;
// Or if complex:
return $order->getBasePrice() - $this->calculateDiscount($order);
6. Use Collection Methods
// BEFORE: Manual loop
$active = [];
foreach ($users as $user) {
if ($user->isActive()) {
$active[] = $user;
}
}
// AFTER: array_filter
$active = array_filter($users, fn($user) => $user->isActive());
// BEFORE: Manual map
$emails = [];
foreach ($users as $user) {
$emails[] = $user->getEmail();
}
// AFTER: array_map
$emails = array_map(fn($user) => $user->getEmail(), $users);
// BEFORE: Manual find
$found = null;
foreach ($items as $item) {
if ($item->getId() === $id) {
$found = $item;
break;
}
}
// AFTER: Collection method
$found = $collection->first(fn($item) => $item->getId() === $id);
7. Replace Switch with Polymorphism
// BEFORE: Switch on type
public function calculateShipping(Order $order): Money
{
switch ($order->getShippingMethod()) {
case 'standard':
return $this->calculateStandardShipping($order);
case 'express':
return $this->calculateExpressShipping($order);
case 'overnight':
return $this->calculateOvernightShipping($order);
default:
throw new InvalidMethodException();
}
}
// AFTER: Strategy pattern
interface ShippingCalculator {
public function calculate(Order $order): Money;
}
class StandardShipping implements ShippingCalculator {}
class ExpressShipping implements ShippingCalculator {}
public function calculateShipping(Order $order): Money
{
return $this->shippingCalculators
->get($order->getShippingMethod())
->calculate($order);
}
8. Null Object Pattern
// BEFORE: Null checks everywhere
if ($user->getAddress() !== null) {
echo $user->getAddress()->getCity();
} else {
echo 'Unknown';
}
// AFTER: Null Object
class NullAddress implements AddressInterface
{
public function getCity(): string
{
return 'Unknown';
}
}
// Always safe to call
echo $user->getAddress()->getCity();
9. Guard Clauses
// BEFORE: Deeply nested
public function process(Request $request): Response
{
if ($request !== null) {
if ($request->isValid()) {
if ($this->canProcess($request)) {
return $this->doProcess($request);
} else {
return $this->error('Cannot process');
}
} else {
return $this->error('Invalid request');
}
} else {
return $this->error('No request');
}
}
// AFTER: Guard clauses
public function process(Request $request): Response
{
if ($request === null) {
return $this->error('No request');
}
if (!$request->isValid()) {
return $this->error('Invalid request');
}
if (!$this->canProcess($request)) {
return $this->error('Cannot process');
}
return $this->doProcess($request);
}
10. Use Modern PHP Features
// BEFORE: Old syntax
$name = isset($data['name']) ? $data['name'] : 'default';
// AFTER: Null coalescing
$name = $data['name'] ?? 'default';
// BEFORE: Property assignment
$value = $object->getValue();
if ($value !== null) {
echo $value;
}
// AFTER: Nullsafe operator
echo $object?->getValue();
// BEFORE: Match as if/else
if ($status === 'active') {
$color = 'green';
} elseif ($status === 'pending') {
$color = 'yellow';
} else {
$color = 'red';
}
// AFTER: Match expression
$color = match($status) {
'active' => 'green',
'pending' => 'yellow',
default => 'red',
};
Severity Classification
| Pattern | Severity |
|---|---|
| Deeply nested code | 🟠Major |
| Repeated code blocks | 🟠Major |
| Complex boolean expressions | 🟡 Minor |
| Old syntax available in modern PHP | 🟢 Suggestion |
| Verbose but clear code | 🟢 Suggestion |
Output Format
### Simplification: [Description]
**Severity:** 🟠/🟡/🟢
**Location:** `file.php:line`
**Type:** [Extract Method|Guard Clause|Collection Method|...]
**Issue:**
[Description of the complexity]
**Current:**
```php
// Complex code
Suggested:
// Simplified code
Benefits:
- Improved readability
- Reduced cognitive load
- Easier testing
- Better reusability
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12