/laravel-agent:refactor
Analyze and refactor code for SOLID/DRY compliance
Overview
The /refactor command invokes the laravel-refactor agent to analyze your code and improve quality by applying SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion) and DRY (Don't Repeat Yourself) best practices. It detects code smells, proposes fixes, implements improvements incrementally, and verifies all tests pass.
Usage
/laravel-agent:refactor [target]
Parameters
- target - File path, class name, or directory to refactor
Examples
# Refactor a specific controller
/laravel-agent:refactor app/Http/Controllers/OrderController.php
# Refactor by class name
/laravel-agent:refactor OrderService
# Refactor an entire directory
/laravel-agent:refactor app/Services/
What Gets Analyzed
The refactor agent examines your code for common quality issues:
| Code Smell | SOLID/DRY Principle | Refactoring Applied |
|---|---|---|
| Long methods (>20 lines) | Single Responsibility | Extract smaller methods |
| God classes (>300 lines) | Single Responsibility | Split into focused classes |
| Duplicate code blocks | DRY (Don't Repeat Yourself) | Extract reusable methods/traits |
| Tight coupling | Dependency Inversion | Inject interfaces, use dependency injection |
| Complex conditionals | Open/Closed | Strategy pattern or polymorphism |
| Multiple responsibilities | Single Responsibility | Separate concerns into services |
| Feature envy | Single Responsibility | Move method to appropriate class |
| Primitive obsession | Interface Segregation | Create value objects or DTOs |
Refactoring Process
The agent follows a systematic approach to ensure safe, incremental improvements:
- Analysis - Scan target code for SOLID/DRY violations and code smells
- Proposal - Present identified issues with suggested fixes
- Implementation - Apply refactorings incrementally, one improvement at a time
- Verification - Run tests after each change to ensure functionality is preserved
- Report - Summarize improvements with before/after metrics
Example Before & After
Before refactoring - controller with multiple responsibilities:
<?php
namespace App\Http\Controllers;
use App\Models\Order;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\OrderConfirmation;
class OrderController extends Controller
{
public function store(Request $request)
{
// Validation mixed with business logic
$validated = $request->validate([
'customer_email' => 'required|email',
'items' => 'required|array',
'items.*.product_id' => 'required|exists:products,id',
'items.*.quantity' => 'required|integer|min:1',
]);
// Calculate total inline
$total = 0;
foreach ($validated['items'] as $item) {
$product = Product::find($item['product_id']);
$total += $product->price * $item['quantity'];
}
// Create order
$order = Order::create([
'customer_email' => $validated['customer_email'],
'total' => $total,
'status' => 'pending',
]);
// Create order items inline
foreach ($validated['items'] as $item) {
$order->items()->create([
'product_id' => $item['product_id'],
'quantity' => $item['quantity'],
]);
}
// Send email directly in controller
Mail::to($order->customer_email)->send(new OrderConfirmation($order));
return response()->json($order, 201);
}
}
After refactoring - separated concerns with dependency injection:
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreOrderRequest;
use App\Http\Resources\OrderResource;
use App\Services\OrderService;
class OrderController extends Controller
{
public function __construct(
private OrderService $orderService
) {}
public function store(StoreOrderRequest $request)
{
$order = $this->orderService->createOrder(
$request->validated()
);
return new OrderResource($order);
}
}
// app/Http/Requests/StoreOrderRequest.php
class StoreOrderRequest extends FormRequest
{
public function rules(): array
{
return [
'customer_email' => 'required|email',
'items' => 'required|array',
'items.*.product_id' => 'required|exists:products,id',
'items.*.quantity' => 'required|integer|min:1',
];
}
}
// app/Services/OrderService.php
class OrderService
{
public function __construct(
private OrderCalculator $calculator,
private OrderNotifier $notifier
) {}
public function createOrder(array $data): Order
{
$total = $this->calculator->calculateTotal($data['items']);
$order = Order::create([
'customer_email' => $data['customer_email'],
'total' => $total,
'status' => 'pending',
]);
$this->createOrderItems($order, $data['items']);
$this->notifier->sendConfirmation($order);
return $order->fresh('items');
}
private function createOrderItems(Order $order, array $items): void
{
foreach ($items as $item) {
$order->items()->create([
'product_id' => $item['product_id'],
'quantity' => $item['quantity'],
]);
}
}
}
Output Report Format
After refactoring completes, you'll receive a detailed summary:
## Refactoring Complete: OrderController
### Issues Fixed
| Issue | Fix Applied |
|-------|-------------|
| God class (150 lines) | Extracted OrderService, OrderCalculator, OrderNotifier |
| Multiple responsibilities | Separated validation, business logic, notifications |
| Tight coupling to Mail facade | Injected OrderNotifier dependency |
| Inline calculations | Extracted OrderCalculator service |
### Improvements
- Lines: 150 → 45 (70% reduction)
- Methods: 8 → 2 (focused on HTTP concerns)
- Cyclomatic complexity: 12 → 4
- Test coverage: 65% → 92%
### Tests: All passing ✓
- 24 tests, 89 assertions
- 0 failures, 0 errors
Focus Areas
The agent can focus on specific refactoring concerns by including hints in your command:
- general (default) - All SOLID/DRY principles
- extract methods - Break down long methods
- reduce coupling - Add dependency injection
- remove duplication - DRY principle focus
- split classes - Single Responsibility focus
Best Practices
- Commit before refactoring - Ensure you can rollback if needed
- Have tests in place - Refactoring requires test coverage to verify behavior
- Refactor incrementally - The agent applies one change at a time for safety
- Review proposed changes - Understand each improvement before applying
- Run full test suite - Verify all tests pass after refactoring
When to Refactor
Consider refactoring when you notice:
- Controllers exceeding 100 lines or methods exceeding 20 lines
- Copy-pasted code blocks across multiple files
- Difficulty adding new features without modifying existing code
- Hard-to-test code due to tight coupling
- Classes doing too many unrelated things
- Complex nested conditionals or switch statements
Related Agent
This command uses the laravel-refactor agent with access to Task, Read, Glob, Grep, Bash, Write, Edit, and MultiEdit tools.
See Also
- /laravel-agent:test:make - Generate tests for refactored code
- /laravel-agent:code-review - Review code quality without refactoring
- laravel-testing skill - Ensure test coverage before refactoring