Design Patterns In Laravel
Laravel follows several design patterns to ensure code maintainability, scalability, reuseablitity and efficiency. Here are some of the design patterns used in PHP Laravel:
1. MVC (Model-View-Controller):
Laravel follows the MVC pattern, which separates business logic (Model), presentation (View), and request handling (Controller).
2. Repository Pattern:
Used to abstract the data layer and make database queries reusable and independent of the framework. This pattern helps in separating database queries from controllers. for example:
interface UserRepositoryInterface {
public function getAllUsers();
}
class UserRepository implements UserRepositoryInterface {
public function getAllUsers() {
return User::all();
}
}
In controller
class UserController {
private $userRepository;
public function __construct(UserRepositoryInterface $userRepository) {
$this->userRepository = $userRepository;
}
public function index() {
$users = $this->userRepository->getAllUsers();
return view('users.index', compact('users'));
}
}
3. Service Pattern:
In this patterns all the business logic from controllers are moved to service classes. For Example:
// Service class
class UserService {
public function createUser($data) {
return User::create($data);
}
}
// In Controller:
class UserController {
private $userService;
public function __construct(UserService $userService) {
$this->userService = $userService;
}
public function store(Request $request) {
$this->userService->createUser($request->all());
return redirect()->back();
}
}
4. Dependency Injection:
Laravel injects dependencies into classes instead of creating them manually.
class UserController {
public function __construct(public UserService $userService) {}
}
5. Singleton Pattern:
Used when a class should have only one instance throughout the application. This pattern is mostly used in laravel facades and service providers. For Example:
class Logger {
private static $instance;
private function __construct() {}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new Logger();
}
return self::$instance;
}
}
6. Observer Pattern:
Laravel uses Eloquent Observers to listen for model events like creating, updating, deleting. For example:
class UserObserver {
public function creating(User $user) {
$user->uuid = Str::uuid();
}
}
// Registered in AppServiceProvider
public function boot() {
User::observe(UserObserver::class);
}
7. Strategy Pattern:
Allows defining a family of algorithms and choosing one at runtime. For example Payment Strategies:
interface PaymentStrategy {
public function pay($amount);
}
class PaypalPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paid $amount using PayPal.";
}
}
class CreditCardPayment implements PaymentStrategy {
public function pay($amount) {
echo "Paid $amount using Credit Card.";
}
}
class PaymentContext {
private $strategy;
public function __construct(PaymentStrategy $strategy) {
$this->strategy = $strategy;
}
public function executePayment($amount) {
return $this->strategy->pay($amount);
}
}
// Usages
$payment = new PaymentContext(new PaypalPayment());
$payment->executePayment(100);
8. Command Pattern:
used for CLI commands
class SendEmails extends Command {
protected $signature = 'email:send';
protected $description = 'Send emails to users';
public function handle() {
$this->info('Emails sent successfully.');
}
}
9. Decorator Pattern:
In laravel it is used for request handling(mostly used in middleware to modify the request/response objects). Example:
class VerifyUserMiddleware {
public function handle($request, Closure $next) {
if (!$request->user()->verified) {
return redirect('verify-email');
}
return $next($request);
}
}
Thank you for reading. Before you go 🙋♂️:
Please clap for the writer ️️️
🏌️Follow me: https://medium.com/@sandeeppant