Task Manager: Refactoring for Clean Code
Learn to refactor your Task Manager by moving business logic into Service classes, cleaning up controllers, and simplifying your Blade templates.
Previously in this course, we covered Task Manager: Completing CRUD Functionality in Laravel. We built a functional, secure application, but as our logic grows, our controllers are starting to look a bit crowded.
In this lesson, we are applying refactoring to achieve clean code by extracting business logic from controllers into dedicated Service classes. This separation of concerns ensures your controllers stay thin, focused only on handling the HTTP request and returning a response.
Why Refactor Your Task Manager?
As you add more features to your Task Manager, your controller methods often become "god methods"—they handle validation, database queries, business rules, and response formatting. This makes the code hard to test and even harder to maintain.
By moving business logic into a "Service" layer, we gain:
- Reusability: You can call the same logic from a controller, an Artisan command, or a background job.
- Testability: It is much easier to write unit tests for a Service class than for a controller that requires an HTTP request context.
- Readability: Your controllers become thin "traffic cops" that simply route traffic to the right place.
Moving Logic to Services
Let's look at a common task: creating a new task. Currently, your controller might be handling the database insertion and any side effects (like logging or sending notifications).
Create a new directory at app/Services and create a TaskService.php file:
PHPnamespace App\Services; use App\Models\Task; use Illuminate\Support\Facades\Auth; class TaskService { public function createTask(array $data): Task { return Auth::user()->tasks()->create([ 'title' => $data['title'], 'description' => $data['description'], 'priority' => $data['priority'] ?? 'medium', ]); } }
Now, inject this service into your TasksController. Instead of the controller knowing how to build a task, it just asks the service to do it.
PHP#6A9955">// In TasksController.php public function store(StoreTaskRequest $request, TaskService $service) { $service->createTask($request->validated()); return redirect()->route('tasks.index')->with('success', 'Task created!'); }
Simplifying Blade Templates
Clean code isn't just for your PHP classes; it extends to your views. If you find yourself repeating logic in your Blade files—like calculating CSS classes based on task priority—extract that logic.
Instead of writing complex @if statements inside your loop, define a method on your Task model to handle the presentation logic:
PHP#6A9955">// In App\Models\Task.php public function getPriorityColorAttribute(): string { return match($this->priority) { 'high' => 'text-red-600', 'low' => 'text-green-600', default => 'text-gray-600', }; }
Now, your Blade template becomes significantly cleaner and easier to read:
HTMLstyle="color:#808080"><style="color:#4EC9B0">span class="{{ $task->priority_color }}"> {{ ucfirst($task->priority) }} style="color:#808080"></style="color:#4EC9B0">span>
Hands-on Exercise
- Create the Service: Generate an
app/Services/TaskService.phpfile. - Refactor: Identify one controller method (like
updateordelete) that contains more than just a simple Eloquent call. Move that logic into your newTaskService. - Clean the View: Check your
index.blade.php. If you are using complex logic to display task status or priority, move that logic into a helper method or an accessor within theTaskmodel.
Common Pitfalls
- Over-Engineering: Don't create a Service class for every single action. If a controller method is just
Task::create($request->all()), keep it in the controller. Use Services for complex workflows. - Injecting Services in the Wrong Place: Remember that you can type-hint classes in your controller methods, and Laravel’s Service Container will automatically inject them for you.
- Ignoring Eloquent: Don't move basic database queries into Services. Eloquent is designed to handle those. Use Services for business workflows (e.g., "When a task is completed, notify the manager, update the history log, and archive the file").
Recap
Refactoring for clean code is an iterative process. By moving business logic into Services, keeping your controllers thin, and leveraging Model accessors for view-level logic, you ensure your Task Manager remains maintainable as it evolves. You have successfully separated your concerns, making your application more robust and easier to test.
Up next: We will begin writing our first automated tests to ensure our refactored code works exactly as expected.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.
