Kritim Yantra
Mar 08, 2025
Laravel is a powerful PHP framework that makes web development easier and more enjoyable. One of the reasons for its popularity is its use of design patterns, which are like recipes or blueprints for solving common problems in software development. These patterns provide tried-and-tested solutions that you can adapt to your projects, making your code more organized, maintainable, and scalable.
In this blog, we’ll explore some of the key design patterns used in Laravel, explain them in simple terms, and provide code examples to help beginners understand how they work. We’ll cover the MVC Pattern, Dependency Injection, Facade Pattern, and briefly touch on the Repository Pattern. Let’s dive in!
Imagine you’re cooking a meal. A recipe tells you the steps to follow to make a delicious dish. Similarly, a design pattern is a reusable solution to a common problem in software design. It’s not a piece of code you copy-paste but a template you can customize for your needs.
Laravel uses several design patterns to streamline development. In this guide, we’ll focus on the ones you’ll encounter most often as a beginner.
The Model-View-Controller (MVC) pattern is the foundation of Laravel’s structure. It splits your application into three main parts:
How It Works in Laravel: Models in Laravel are typically Eloquent ORM classes representing database tables. Views are Blade templates that generate HTML, and controllers handle HTTP requests by coordinating between models and views.
Code Example: Displaying a List of Users
Step 1: The Model
<?php
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model {
// This Eloquent model interacts with the 'users' table
protected $fillable = ['name', 'email'];
}
Step 2: The Controller
<?php
// app/Http/Controllers/UserController.php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller {
public function index() {
// Fetch all users from the database
$users = User::all();
// Pass the users to the view
return view('users.index', compact('users'));
}
}
Step 3: The View
<!-- resources/views/users/index.blade.php -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Users List</title>
</head>
<body>
<h1>Users List</h1>
<ul>
@foreach ($users as $user)
<li>{{ $user->name }} ({{ $user->email }})</li>
@endforeach
</ul>
</body>
</html>
Step 4: The Route
<?php
// routes/web.php
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
When you visit /users
in your browser, the UserController fetches all users from the User model and passes them to the Blade template to display them as a list.
Dependency Injection (DI) is a way to supply a class with its required dependencies from the outside rather than creating them within the class. This makes your code more flexible, testable, and easier to maintain.
In Laravel, the service container handles DI automatically. You can inject services or classes into controllers, middleware, or even method parameters.
Code Example: Injecting a User Service
Step 1: The Service
<?php
// app/Services/UserService.php
namespace App\Services;
use App\Models\User;
class UserService {
public function getAllUsers() {
return User::all();
}
}
Step 2: The Controller
<?php
// app/Http/Controllers/UserController.php
namespace App\Http\Controllers;
use App\Services\UserService;
class UserController extends Controller {
protected $userService;
// Inject UserService via the constructor
public function __construct(UserService $userService) {
$this->userService = $userService;
}
public function index() {
$users = $this->userService->getAllUsers();
return view('users.index', compact('users'));
}
}
Here, Laravel’s service container automatically injects an instance of UserService into the controller.
The Facade Pattern provides a simple, static-like interface to access services in the service container. Facades make your code cleaner by hiding the complexity of dependency resolution.
Code Example: Using the Cache Facade
<?php
// In a controller or anywhere in your app
use Illuminate\Support\Facades\Cache;
class ExampleController extends Controller {
public function testCache() {
// Store a value in the cache for 10 minutes
Cache::put('key', 'Hello, Laravel!', 10);
// Retrieve the value
$value = Cache::get('key');
return $value; // Outputs: Hello, Laravel!
}
}
Facades like Cache
provide a clear, concise way to interact with Laravel's underlying services.
The Repository Pattern abstracts the data access layer, so your controllers don’t directly interact with the models. This makes it easier to swap out data sources (like changing the database) and improves testability.
Code Example: A User Repository
Step 1: The Repository
<?php
// app/Repositories/UserRepository.php
namespace App\Repositories;
use App\Models\User;
class UserRepository {
public function all() {
return User::all();
}
public function find($id) {
return User::find($id);
}
}
Step 2: The Controller
<?php
// app/Http/Controllers/UserController.php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
class UserController extends Controller {
protected $userRepository;
public function __construct(UserRepository $userRepository) {
$this->userRepository = $userRepository;
}
public function index() {
$users = $this->userRepository->all();
return view('users.index', compact('users'));
}
}
Although using the Repository Pattern is optional for beginners, it becomes valuable as your application grows.
Design patterns are powerful tools that help you write better code in Laravel. Here’s a quick recap:
As a beginner, start by getting comfortable with MVC, then gradually explore Dependency Injection and Facades. These patterns will give you a strong foundation for building robust Laravel applications.
Keep practicing, and soon you’ll be using these patterns naturally in your projects. Happy coding!
No comments yet. Be the first to comment!
Please log in to post a comment:
Continue with Google