Wednesday, 8 January 2025

Laravel Project structure combines SOLID principles and Design patterns in Laravel

I. SOLID principles

1. Single Responsibility Principle (SRP)

Adopt a modular structure that respects SRP (Single Responsibility Principle) and facilitates the use of design patterns:

app/ ├── Actions/ # For Single Action Classes ├── Contracts/ # For Interfaces ├── DTOs/ # For Data Transfer Objects ├── Events/ # For Events ├── Exceptions/ # For Custom Exceptions ├── Http/ │ ├── Controllers/ # REST/GraphQL Controllers │ ├── Middleware/ # Middleware Classes │ ├── Requests/ # Form Request Validation ├── Jobs/ # For Jobs and Commands ├── Listeners/ # For Event Listeners ├── Models/ # Eloquent Models ├── Observers/ # For Model Observers ├── Policies/ # For Authorization Logic ├── Providers/ # Service Providers ├── Repositories/ # Repository Pattern ├── Rules/ # Custom Validation Rules ├── Services/ # Service Layer for Business Logic └── ViewModels/ # For View Model Logic

2. Open/Closed Principle (OCP)

  • Use Strategy Pattern to extend functionality without modifying existing code.

3. Liskov Substitution Principle (LSP)

  • Rely on abstractions (Contracts), and ensure derived classes are substitutable.

4. Interface Segregation Principle (ISP)

  • Use smaller, specific interfaces (e.g., UserRepositoryInterface, PostRepositoryInterface).

5. Dependency Inversion Principle (DIP)

  • Inject dependencies using Laravel's Service Container.
II. Essential Design Patterns in Laravel

1. Repository Pattern

  • Create repositories for data access:
    • Example: UserRepository for interacting with user data.
    namespace App\Repositories; use App\Models\User; class UserRepository implements UserRepositoryInterface { public function findById($id) { return User::find($id); } }

2. Service Pattern

  • Move business logic to services:
    namespace App\Services; use App\Repositories\UserRepositoryInterface; class UserService { protected $userRepository; public function __construct(UserRepositoryInterface $userRepository) { $this->userRepository = $userRepository; } public function getUserProfile($id) { return $this->userRepository->findById($id); } }

3 Factory Pattern

  • Use Laravel's built-in factories for generating test data:
    User::factory()->create();

4. Strategy Pattern

  • Implement strategies for interchangeable algorithms:
    namespace App\Services\Payment; interface PaymentStrategy { public function pay($amount); } class PaypalPayment implements PaymentStrategy { public function pay($amount) { // Pay with PayPal } } class CreditCardPayment implements PaymentStrategy { public function pay($amount) { // Pay with Credit Card } }

5 Observer Pattern

  • Use model observers for handling model events:
    namespace App\Observers; use App\Models\User; class UserObserver { public function created(User $user) { // Send welcome email } }

6 Decorator Pattern

  • Extend existing functionalities dynamically:
    namespace App\Services; class LoggerDecorator { protected $service; public function __construct($service) { $this->service = $service; } public function execute() { \Log::info('Executing service'); return $this->service->execute(); } }

7 Builder Pattern

  • Chain complex object creation:
    namespace App\Builders; class UserQueryBuilder { protected $query; public function __construct() { $this->query = User::query(); } public function whereActive() { $this->query->where('active', true); return $this; } public function whereRole($role) { $this->query->where('role', $role); return $this; } public function get() { return $this->query->get(); } }
Thank you

No comments:

Post a Comment

Golang Advanced Interview Q&A