Hiểu về "Janitor Pattern": Vấn đề kiến trúc quan trọng trong phát triển frontend
Janitor Pattern là hiện tượng phổ biến trong các dự án frontend khi codebase ngày càng khó duy trì do quan niệm sai lầm rằng frontend chỉ là lớp giao diện người dùng. Bài viết phân tích nguồn gốc, chi phí thực sự, và cách tổ chức lại kiến trúc frontend theo hướng có kỷ luật để cải thiện hiệu suất và chất lượng.

Hiểu về "Janitor Pattern": Vấn đề kiến trúc quan trọng trong phát triển frontend
Hiện tượng “Janitor Pattern” tồn tại ngấm ngầm trong hầu hết các đội frontend mà hiếm khi được nhắc đến chính thức. Đây là trạng thái khi các kỹ sư frontend dành phần lớn thời gian gỡ rối và duy trì sự ổn định của mã nguồn cũ thay vì xây dựng tính năng mới. Nguyên nhân căn bản không phải do năng lực dev yếu, mà xuất phát từ nhận thức sai lầm coi frontend chỉ là lớp giao diện đơn giản bên ngoài — nơi được giao cho nhân lực ít kinh nghiệm, bị xem nhẹ trong quá trình phát triển hệ thống.
Janitor Pattern phát sinh như thế nào?
Janitor Pattern hiếm khi đến từ một quyết định rõ ràng mà thường bắt đầu từ mô hình phân bổ nhân sự:
- Backend nhận được kiến trúc sư cấp cao, quy trình đánh giá thiết kế (ADR), và quyền sở hữu rõ ràng các lớp dữ liệu.
- Frontend thường chỉ được giao cho những ai còn lại, giá rẻ hơn, hoặc đủ điều kiện để giao “ship component”.
Điều này ngầm gửi đi thông điệp rằng frontend không cần đầu tư về kiến trúc hay kỹ thuật nghiêm túc. Hậu quả là:
- Không có tiêu chuẩn kiến trúc frontend thống nhất.
- Mỗi kỹ sư tự ra quyết định cục bộ, dẫn đến hệ thống thiếu trật tự, rò rỉ trạng thái giữa các thành phần không liên quan.
- Các component trở nên phình to, lẫn lộn logic giao diện lẫn logic nghiệp vụ, làm mã nguồn phức tạp, khó bảo trì.
- Quản lý lãnh đạo dễ nhận định sai rằng frontend vốn dĩ là “mớ hỗn độn”, nhưng thực ra đó là hậu quả của việc không ai có quyền hoặc thời gian để kiểm soát hệ thống này.
Chi phí thật sự của Janitor Pattern
Chi phí của vấn đề này không chỉ là hiệu suất phát triển giảm dần mà còn ảnh hưởng sâu rộng khác:
- Mất tốc độ phát triển: Ban đầu, nhóm có thể vận hành nhanh do quy mô code nhỏ. Nhưng theo thời gian, tính năng mới mất tới 2, 4 lần thời gian ban đầu do độ phức tạp tích lũy.
- Chất lượng kỹ sư giảm: Kỹ sư cao cấp thường chịu đựng được một thời gian nhưng rồi bỏ đi, để lại nhóm chỉ còn những người không nhận ra hoặc không quan tâm đến vấn đề, khiến tình trạng càng tồi tệ hơn.
- Tính năng không được xây dựng: Thời gian dành cho gỡ rối tích lũy, ngăn cản phát triển tính năng mới. Đây là chi phí vô hình không thể đo đếm rõ trên báo cáo, nhưng ảnh hưởng trực tiếp đến năng lực cạnh tranh sản phẩm.
Frontend thực sự là một hệ thống phức tạp
Xét về mặt kỹ thuật, frontend không chỉ là "lớp giao diện". Một ứng dụng frontend hiện đại xử lý:
- Quản lý trạng thái phức tạp.
- Thực thi các quy tắc nghiệp vụ.
- Đồng bộ bất đồng bộ với backend.
- Định nghĩa các hợp đồng dữ liệu.
- Đảm bảo an toàn bảo mật (quản lý xác thực, điều hướng…).
- Xử lý và trình bày lỗi cho người dùng.
- Quyết định caching, điều hướng, hiển thị.
Frontend có thể phức tạp và yêu cầu kỷ luật tương đương backend.
Những nguyên tắc nổi bật cần áp dụng cho frontend cũng như backend gồm:
- Nguyên tắc phân tách rõ ràng (Separation of concerns).
- Dòng dữ liệu rõ ràng, trách nhiệm ràng buộc từng phần.
- Component chỉ nên đảm nhận một nhiệm vụ (Single Responsibility Principle - SOLID).
- Giữ các component đơn giản, tránh over-engineering (KISS - Keep It Simple, Stupid).
- Xây dựng tính năng vừa đủ cần thiết (YAGNI - You Aren't Gonna Need It).
Việc để một component frontend làm quá nhiều việc (giao diện, quản lý trạng thái, xử lý lỗi, gửi analytics) là vi phạm nguyên tắc này, làm test trở nên khó khăn và thay đổi lỗi dễ phát sinh.
Ví dụ về kiến trúc frontend có kỷ luật
Ở dự án mẫu trò chơi Battleship, tác giả áp dụng thiết kế phân lớp nghiêm ngặt:
- Logic nghiệp vụ nằm hoàn toàn trong các hàm TypeScript thuần, không chứa React hay code giao diện.
- Mô-đun vận hành CLI độc lập cũng dùng lại logic này, chứng minh rõ ràng tách bạch các layer.
- Trạng thái frontend được minimal hóa, toàn bộ các giá trị phái sinh được tính từ dữ liệu gốc, tránh trùng lặp nguồn dữ liệu.
- Mỗi chuyển trạng thái là atomic, tránh đồng bộ hóa không nhất quán.
- Các component frontend chủ yếu “dumb”, chỉ chịu trách nhiệm render và xử lý tương tác UI cơ bản, không chứa logic nghiệp vụ.
Điều này được thực hiện mà không cần thêm framework mới hay thư viện quản lý trạng thái phức tạp — chỉ cần kiên định từ đầu trong việc coi frontend là một hệ thống nghiêm túc.
Cần thay đổi gì để thoát khỏi Janitor Pattern?
Đối với lãnh đạo kỹ thuật:
- Thừa nhận rằng cách tuyển chọn và phân bổ nhân sự cho frontend chính là một quyết định kiến trúc.
- Giao kiến trúc frontend cho kỹ sư có đủ quyền hạn và kinh nghiệm.
- Thiết lập quy trình review kiến trúc bao gồm cả frontend, không chỉ backend.
- Đặt hiệu suất, chất lượng và bảo mật frontend ngang hàng với backend, không phải xử lý “sau cùng”.
Đối với kỹ sư frontend:
- Theo dõi rõ ràng thời gian và chi phí do nợ kiến trúc gây ra, truyền đạt bằng ngôn ngữ lãnh đạo dễ hiểu (ví dụ như ảnh hưởng tới tốc độ ra tính năng).
- Kiên quyết phản đối quan niệm frontend sẽ luôn phức tạp và lộn xộn.
- Đặt mục tiêu phát triển hệ thống có kỷ luật, dễ kiểm soát, dễ mở rộng.
Janitor Pattern tồn tại vì nó khó nhận biết rõ ràng, và thường không ai chịu trách nhiệm đủ để xử lý triệt để. Để giải quyết, cả lãnh đạo và kỹ sư cần cùng nhìn nhận thẳng thắn về thực trạng và thay đổi tư duy tổ chức.
Frontend không chỉ là lớp giao diện. Nó là một hệ thống phức tạp và xứng đáng được xây dựng với tiêu chuẩn kỹ thuật nghiêm ngặt như các hệ thống backend. Chỉ khi đó, các dự án mới tránh được Janitor Pattern để tiếp tục phát triển bền vững.
Bài viết liên quan

Phần mềm
Anthropic ra mắt Claude Opus 4.7: Nâng cấp mạnh mẽ cho lập trình nhưng vẫn thua Mythos Preview
16 tháng 4, 2026

Công nghệ
Qwen3.6-35B-A3B: Quyền năng Lập trình Agentic, Nay Đã Mở Cửa Cho Tất Cả
16 tháng 4, 2026

Công nghệ
Spotify thắng kiện 322 triệu USD từ nhóm pirate Anna's Archive nhưng đối mặt với bài toán thu hồi
16 tháng 4, 2026
