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.
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:
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!'); }
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>
app/Services/TaskService.php file.update or delete) that contains more than just a simple Eloquent call. Move that logic into your new TaskService.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 the Task model.Task::create($request->all()), keep it in the controller. Use Services for complex workflows.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.
Master service-oriented task management in Laravel. Learn to encapsulate task creation and user assignment logic within a service layer for cleaner code.
Task Manager: Refactoring for Clean Code
Using Database Transactions
Handling Global Exceptions
Preparing for Production
Environment Security Best Practices
Managing Assets in Production
Task Manager: Deployment Preparation