+1

Kiến trúc Clean Code trong Laravel: Hướng dẫn thực hành

Nếu bạn đã phát triển ứng dụng với Laravel được một thời gian, có lẽ bạn đã từng nghe đến cụm từ "clean code". Nhưng "clean code" thực sự có ý nghĩa gì trong bối cảnh phát triển Laravel? Quan trọng hơn, tại sao bạn nên quan tâm đến nó?

Clean Code là gì?

"Clean Code" - mã sạch - dùng để chỉ đoạn mã dễ hiểu, dễ bảo trì và dễ mở rộng. Kiến trúc clean code còn tiến thêm một bước nữa bằng cách cung cấp một cấu trúc giúp bạn dễ dàng giữ cho codebase của mình sạch sẽ khi ứng dụng phát triển. Trong blog này, chúng ta sẽ cùng tìm hiểu cách bạn có thể triển khai kiến trúc clean code trong Laravel để giúp các dự án của bạn có khả năng mở rộng, bảo trì tốt hơn và thú vị hơn khi thực hiện.

Kiến trúc Clean Code là gì?

Kiến trúc clean code là một cách tổ chức ứng dụng của bạn để dễ dàng bảo trì và mở rộng. Nó không bị ràng buộc với bất kỳ framework hoặc ngôn ngữ cụ thể nào mà phân tách ứng dụng của bạn thành các lớp. Mỗi lớp có một trách nhiệm cụ thể và được kết nối lỏng lẻo với các lớp khác.

Sự phân tách này giúp bạn tránh được "spaghetti code" khét tiếng, nơi mọi thứ rối tung lên với nhau. Với kiến trúc clean code, logic nghiệp vụ của bạn được tách biệt với giao diện người dùng và truy cập dữ liệu, cho phép bạn thực hiện các thay đổi đối với một phần của ứng dụng mà không ảnh hưởng đến toàn bộ hệ thống.

Viết mã sạch không chỉ là làm cho mã của bạn trông đẹp mắt, nó còn giúp công việc của bạn dễ dàng hơn rất nhiều về lâu dài. Khi mã của bạn sạch sẽ:

  • Dễ debug hơn: Mã rõ ràng, có cấu trúc tốt giúp bạn tìm và sửa lỗi nhanh hơn.
  • Dễ mở rộng hơn: Khi ứng dụng của bạn phát triển, mã sạch sẽ giúp bạn dễ dàng thêm các tính năng mới mà không phá vỡ các tính năng hiện có.
  • Dễ dàng làm việc với những người khác hơn: Cho dù bạn đang làm việc nhóm hay chia sẻ dự án của mình với cộng đồng mã nguồn mở, thì mã sạch sẽ dễ hiểu hơn đối với những người khác.

Trong một framework như Laravel, vốn khuyến khích phát triển nhanh chóng, bạn có thể bị cám dỗ bởi việc tập trung vào xây dựng nhanh chóng hơn là sạch sẽ. Nhưng bằng cách tuân theo các nguyên tắc viết mã sạch, bạn sẽ tiết kiệm được thời gian và công sức về lâu dài.

Các nguyên tắc chính của kiến trúc Clean Code

Trước khi đi sâu vào cách triển khai kiến trúc clean code trong Laravel, chúng ta hãy cùng tìm hiểu một số nguyên tắc chính:

  • Phân tách mối quan tâm (Separation of Concerns): Mỗi lớp trong kiến trúc của bạn phải có một trách nhiệm cụ thể và bạn nên tránh trộn lẫn các mối quan tâm (ví dụ: không đặt logic cơ sở dữ liệu trong bộ điều khiển của bạn).
  • Đảo ngược dependency (Dependency Inversion): Các mô-đun cấp cao hơn không nên phụ thuộc vào các mô-đun cấp thấp hơn. Thay vào đó, cả hai nên phụ thuộc vào các phần trừu tượng (như giao diện).
  • Nguyên tắc trách nhiệm duy nhất (Single Responsibility Principle): Mỗi lớp hoặc hàm chỉ nên làm một việc và làm tốt việc đó. Điều này giúp bạn dễ dàng kiểm tra và bảo trì mã của mình hơn.

Hướng dẫn triển khai kiến trúc Clean Code

Cốt lõi của kiến trúc clean code là thực thể và trường hợp sử dụng. Thực thể là các đối tượng cốt lõi trong hệ thống của bạn (như Bài đăng hoặc Người dùng) và trường hợp sử dụng xác định những gì bạn có thể làm với các thực thể đó (như tạo bài đăng hoặc xóa người dùng).

Trong Laravel, các thực thể có thể được biểu diễn dưới dạng các model Eloquent, trong khi các trường hợp sử dụng thường là các service thực hiện các hành động cụ thể trên các model này.

Ví dụ: chúng ta hãy tạo một trường hợp sử dụng đơn giản để tạo một bài đăng trên blog:

// app/Domain/Post/Post.php
class Post {
    private $title;
    private $content;

    public function __construct($title, $content) {
        $this->title = $title;
        $this->content = $content;
    }

    // Getter methods and other domain logic
}

Và đây là một trường hợp sử dụng để tạo một bài đăng mới:

// app/Services/Post/CreatePostService.php
class CreatePostService  
    private $postRepository;
    public function __construct(PostRepositoryInterface $postRepository)  
        $this->postRepository = $postRepository;
     
    public function execute($data)  
        $post = new Post($data['title'], $data['content']);
        $this->postRepository->save($post);

Trong kiến trúc clean code, kho lưu trữ xử lý truy cập dữ liệu và giao diện xác định các method mà kho lưu trữ nên triển khai. Bằng cách này, logic nghiệp vụ của bạn không phụ thuộc vào cơ sở dữ liệu hoặc ORM bạn đang sử dụng — nó phụ thuộc vào phần trừu tượng.

Hãy tạo một giao diện cho PostRepository:

// app/Repositories/PostRepositoryInterface.php
interface PostRepositoryInterface {
    public function save(Post $post): void;
    public function findById($id): ?Post;
}

Và một triển khai Eloquent của kho lưu trữ này:

// app/Repositories/EloquentPostRepository.php
class EloquentPostRepository implements PostRepositoryInterface {
    public function save(Post $post): void {
        // Save post using Eloquent
    }

    public function findById($id): ?Post {
        // Fetch post using Eloquent
    }
}

Bộ điều khiển và Dependency Injection

Bộ điều khiển của bạn nên được tối giản, nghĩa là chúng chỉ nên xử lý các request HTTP và ủy quyền các tác vụ nặng nhọc cho các service. Bằng cách sử dụng tiêm dependency, bạn có thể thêm các service cần thiết vào bộ điều khiển của mình.

// app/Http/Controllers/PostController.php
class PostController {
    private $createPostService;

    public function __construct(CreatePostService $createPostService) {
        $this->createPostService = $createPostService;
    }

    public function store(Request $request) {
        $this->createPostService->execute($request->all());
        return response()->json(['message' => 'Post created!']);
    }
}

Tất cả logic nghiệp vụ của bạn nên nằm trong service. Điều này giúp cho bộ điều khiển của bạn gọn gàng và đảm bảo rằng logic của bạn có thể được sử dụng lại trên các phần khác nhau của ứng dụng.

// app/Services/Post/CreatePostService.php
class CreatePostService {
    private $postRepository;

    public function __construct(PostRepositoryInterface $postRepository) {
        $this->postRepository = $postRepository;
    }

    public function execute($data) {
        $post = new Post($data['title'], $data['content']);
        $this->postRepository->save($post);
    }
}

Ví dụ thực tế: Xây dựng nền tảng blog

Hãy cùng xem qua một ví dụ thực tế về việc xây dựng một nền tảng blog đơn giản. Dưới đây là cách bạn sẽ cấu trúc nó bằng cách sử dụng kiến trúc clean code:

  • Thực thể: Các model Bài đăng và Người dùng của bạn.
  • Kho lưu trữ: Các giao diện như PostRepositoryInterface và UserRepositoryInterface, và các triển khai như EloquentPostRepository.
  • Dịch vụ: CreatePostService, DeletePostService, v.v.
  • Bộ điều khiển: Các bộ điều khiển mỏng ủy quyền công việc cho các service.

Sự phân tách này đảm bảo rằng mã của bạn vẫn mang tính mô-đun và dễ dàng kiểm tra. Ví dụ: nếu bạn quyết định chuyển từ Eloquent sang một ORM khác, bạn sẽ chỉ cần cập nhật việc triển khai kho lưu trữ, chứ không phải toàn bộ ứng dụng của mình.

Các phương pháp hay nhất để tạo Clean Code trong Laravel

  • Giữ cho Bộ điều khiển tối giản: Hãy để service của bạn xử lý logic nghiệp vụ.
  • Sử dụng Tiêm Dependency: Điều này giúp bạn dễ dàng kiểm tra và bảo trì mã của mình hơn.
  • Viết Unit Test: Kiến trúc clean code giúp bạn dễ dàng viết test hơn, vì vậy hãy đảm bảo rằng bạn tận dụng lợi thế đó.
  • Phân tách Mối quan tâm: Giữ logic nghiệp vụ, truy cập dữ liệu và mã trình bày riêng biệt.

Kết luận

Kiến trúc clean code không chỉ dành cho các ứng dụng doanh nghiệp lớn - đó là một tư duy giúp bạn giữ cho codebase của mình sạch sẽ và có tổ chức, ngay cả đối với các dự án có quy mô từ nhỏ đến trung bình. Bằng cách phân tách các mối quan tâm, sử dụng tiêm dependency và tuân theo nguyên tắc trách nhiệm duy nhất, bạn sẽ thấy các ứng dụng Laravel của mình dễ bảo trì, kiểm tra và mở rộng hơn.

Hãy bắt đầu từ những việc nhỏ. Hãy thử refactor một phần của ứng dụng Laravel của bạn để tuân theo kiến trúc clean code và bạn sẽ nhanh chóng thấy được lợi ích của nó.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí