Là một lập trình viên, đâu là những yếu tố kỹ thuật mà bạn quan tâm? Có thể kể đến như technical stack, database, design pattern, clean code... Ngoài những keyword kể trên, có một yếu tố mà bất kì developer nào lúc bắt tay thực hiện đều phải đưa ra quyết định và đóng vai trò không nhỏ trong sự reusable, maintainable của sản phẩm đó chính là Folder Structure.
Phân loại cấu trúc thư mục (folder structure)
Tuỳ thuộc vào độ phức tạp của project, chúng ta sẽ apply những structure thích hợp. Về khái niệm của chúng thì có thể dễ dàng tìm kiếm trên Google hoặc ChatGPT.... Dưới đây mình xin chia sẻ dưới góc độ Frontend sau khi đã apply nó trong việc migrate các legacy code cho Garoon frontend vừa qua.
Đối với những bạn chưa từng đọc series này trước đây, Garoon là một sản phẩm groupware có tuổi đời lâu năm tại Cybozu. Để hiểu rõ hơn về các thách thức mà phía Front-end có thể gặp phải trong quá trình duy trì và phát triển sản phẩm này qua nhiều năm, bạn có thể tham khảo bài viết dưới đây
Những vấn đề Front-end có thể đối mặt với việc duy trì sự phát triển một sản phẩm lâu năm
Sau đây là một vài loại folder structure đã và đang được sử dụng phổ biến, có thể kể đến một vài cái tên sau đây
Phân chia thư mục theo loại file (folder by Type)
Cái tên nói lên tất cả, các file/folder sẽ được tổ chức theo Type. Mỗi loại thành phần sẽ được đặt trong một thư mục riêng biệt, giúp tạo ra một cấu trúc cây thư mục theo loại thành phần. Ví dụ trong một dự án React ta có thể biểu diễn dưới dạng sau
/my-app
|-- /components chứa tất cả các React components.
|-- /services chứa các file liên quan đến việc gọi API hoặc thực hiện các tác vụ liên quan đến dịch vụ.
|-- /utils chứa các hàm tiện ích được sử dụng trong suốt application
|-- /tests chứa tất cả các file kiểm thử
Mô hình tổ chức theo Folder by Type giúp dễ dàng tracking và maintain source code, đồng thời giúp người phát triển tập trung vào các loại thành phần cụ thể mà họ đang làm việc
Phân chia thư mục theo chức năng (folder by Feature)
Tương tự thì phương pháp tổ chức này sẽ phân loại theo tính năng của ứng dụng. Thay vì chia thành phần theo loại (như Folder by Type), Folder by Feature tập trung vào việc đặt các thành phần liên quan vào cùng một thư mục nếu chúng làm việc để triển khai một tính năng hay chức năng cụ thể.
Có thể tham khảo thông qua ví dụ e-commerce web sau
/my-app
|-- /user chứa tất cả các file liên quan đến quản lý người dùng, như đăng nhập, đăng ký, quên mật khẩu, v.v.
|-- /product chứa tất cả các file liên quan đến việc hiển thị và tìm kiếm sản phẩm.
|-- /card chứa tất cả các file liên quan đến giỏ hàng của người dùng.
|-- /payment chứa tất cả các file liên quan đến việc xử lý thanh toán.
Mô hình tổ chức theo Folder by Feature giúp giữ cho các phần của hệ thống được gắn kết chặt chẽ với nhau và dễ hiểu về mặt nghiệp vụ cũng như source code. Nó cũng hỗ trợ tính modular, cho phép các nhóm phát triển độc lập trên các tính năng khác nhau mà không gặp xung đột lớn về mã nguồn.
Và một số kiểu khác như Folder by Domain, Folder by Layer, Folder by Tech, Folder by Functionality...
Garoon Frontend Folder Structure
Trong các bài viết trước có đề cập thì theo thời gian Garoon đang chứa rất nhiều loại hình như Smarty, Javascript, Typescript, React, ... Dev team đã và đang migrate để dễ dàng trong công cuộc maintain cũng như phát triển tính năng mới. Sau quá trình tìm hiểu và cân nhắc kỹ lưỡng, sau đây là một ví dụ về folder structure của Garoon
▼ bulletin
▼ article
▼ components
- ArticleForm.component.ts
- ...
▼ models
- Article.model.ts
- ...
▼ pages
- Create.page.ts
- View.page.ts
- ...
▼ services
- ArticleApi.service.ts
- ...
▼ article-list
- ArticleList.component.ts
- ArticleListApi.service.ts
- ArticleListItem.component.ts
- Index.page.ts
▼ shared ← Shared modules used within the "bulletin" app
- module-x.ts
- module-y.ts
Vâng, đây là kết quả của việc kết hợp giữa 2 phương pháp trên Folder by Feature và Folder by Type.
Việc kết hợp hai kiểu tổ chức source code là Folder by Feature và Folder by Type có thể mang lại một số lợi ích cho dự án phần mềm. Dưới đây là một số lợi ích chính:
Tính Rõ Ràng và Dễ Hiểu:
- Folder by Feature: Giúp tập trung tất cả các thành phần của một tính năng cụ thể vào một thư mục. Điều này làm cho code trở nên rõ ràng và dễ hiểu hơn vì bạn có thể tìm thấy tất cả các phần liên quan đến một tính năng ở cùng một nơi.
- Folder by Type: Giúp phân chia code theo loại, chẳng hạn như controllers, models, services, và các thành phần khác. Điều này làm cho cấu trúc dự án trở nên logic và dễ dàng theo dõi.
Dễ Dàng Quản Lý Tăng Cường Tính Module:
- Folder by Feature: Hỗ trợ tính module bằng cách chia dự án thành các phần nhỏ, mỗi phần đại diện cho một tính năng cụ thể. Điều này giúp quản lý và duy trì code trở nên dễ dàng hơn.
- Folder by Type: Cho phép bạn tập trung vào việc quản lý từng loại thành phần riêng biệt một cách hiệu quả, giúp dự án trở nên có tổ chức hơn.
Tính Tích Hợp Dễ Dàng:
- Folder by Feature: Khi có cần thiết, bạn có thể tích hợp một tính năng mới vào dự án mà không làm ảnh hưởng đến các phần khác. Điều này giúp giảm rủi ro và tăng tính linh hoạt.
- Folder by Type: Dễ dàng thêm các loại mới của thành phần (ví dụ: thêm một loại middleware) mà không ảnh hưởng đến cấu trúc tổ chức chính của tính năng.
Phát triển Đồng Thời:
- Folder by Feature: Cho phép các nhóm phát triển đồng thời trên các tính năng khác nhau mà không gặp xung đột lớn về mã nguồn.
- Folder by Type: Giúp các nhóm chuyên sâu vào các loại cụ thể (như front-end, back-end) mà không làm ảnh hưởng đến công việc của nhau.
Tối Ưu Hóa Tìm Kiếm và Điều Hướng:
- Folder by Feature: Giúp tìm kiếm và điều hướng trở nên hiệu quả hơn khi bạn biết rõ tính năng bạn đang tìm kiếm.
- Folder by Type: Đối với việc tìm kiếm các thành phần cụ thể (ví dụ: tìm tất cả các controllers), cấu trúc theo loại có thể làm cho quá trình này trở nên nhanh chóng và dễ dàng.
Tùy thuộc vào quy mô và yêu cầu cụ thể của dự án, có thể có sự điều chỉnh để phù hợp với ngữ cảnh cụ thể. Đôi khi, một sự kết hợp linh hoạt của cả hai phương pháp có thể mang lại hiệu suất và sự tổ chức tốt nhất cho dự án của bạn.
Kết luận
Xin phép tổng hợp lại, việc tổ chức source code hợp lý rất quan trọng trong quá trình phát triển sản phẩm. Tất nhiên những ví dụ mình đưa ra trên đây không phải là phương án tốt nhất cho mọi project, chỉ là nó phù hợp cho từng ngữ cảnh cụ thể.
Vì không có một cấu trúc nào có thể đáp ứng phù hợp hết cho tất cả mọi project, vì thế hãy bắt đầu dự án của bạn với cấu trúc đơn giản nhất, khi cảm thấy dự án bắt đầu ngày càng phát triển quy mô phức tạp hơn thì hãy nghĩ đến việc tái cấu trúc sang một cấu trúc phù hợp.
Mong bài viết này sẽ có ích cho bạn trong việc đưa ra quyết định sẽ tổ chức source code như thế nào để phù hợp với dự án.