Khi nhắc đến Clean Architecture, nhiều người thường chỉ nghĩ đến backend – nơi cần cấu trúc rõ ràng để quản lý nghiệp vụ phức tạp, xử lý dữ liệu và đảm bảo khả năng mở rộng lâu dài. Tuy nhiên, trong vài năm gần đây, front-end cũng đã “tiến hóa” rất nhiều. Không còn đơn giản là dựng giao diện, front-end cũng đã trở thành nơi chứa logic nghiệp vụ, quản lý trạng thái phức tạp, xử lý dữ liệu realtime, và tương tác chặt chẽ với backend thông qua API… Điều này đặt ra câu hỏi: có nên áp dụng Clean Architecture vào dự án front-end không? Nếu có, thì áp dụng như thế nào?
1. Giới thiệu Clean Architecture
Clean Architecture, được phát triển bởi Robert C. Martin (Uncle Bob), là một cách tổ chức source code nhằm tạo ra một hệ thống dễ bảo trì, dễ mở rộng và dễ kiểm thử. Ý tưởng cốt lõi là tách biệt các lớp (layers) trong ứng dụng để đảm bảo rằng logic nghiệp vụ (business logic) không phụ thuộc vào các chi tiết triển khai như framework, UI, hay cơ sở dữ liệu.
Các thành phần chính của Clean Architecture
Clean Architecture thường được chia thành các tầng (layers) như sau:
- Entities: Đây là tầng cốt lõi, chứa các quy tắc nghiệp vụ (business rules) độc lập với bất kỳ framework hay công nghệ nào. Trong front-end, entities có thể là các đối tượng dữ liệu thuần túy hoặc các hàm xử lý logic nghiệp vụ chính.
- Use Cases: Tầng này chứa các logic nghiệp vụ cụ thể của ứng dụng, ví dụ như cách xử lý dữ liệu, gọi API, hoặc các tương tác chính của người dùng. Use Cases sử dụng Entities và không phụ thuộc vào UI hay framework.
- Interface Adapters: Tầng này chuyển đổi dữ liệu từ Use Cases sang định dạng phù hợp với UI hoặc ngược lại. Trong front-end, đây có thể là các component React hoặc các hàm gọi API.
- Frameworks & Drivers: Tầng ngoài cùng, chứa các chi tiết triển khai như UI (React, Vue, v.v.), thư viện, hoặc các công cụ giao tiếp với bên ngoài (API, localStorage).
Cấu trúc này thường được minh họa bằng một sơ đồ đồng tâm, với Entities ở trung tâm và Frameworks & Drivers ở ngoài cùng.

2. Kết hợp React với Clean Architecture liệu có khả thi ?
Câu trả lời là hoàn toàn CÓ, nhưng phải đúng trường hợp. React nổi tiếng là 1 thư viện dễ tiếp cận và dễ sử dụng. Điều này đồng nghĩa với việc dù có tổ chức source code có chuẩn hay không thì vẫn có thể chạy được. Việc áp dụng Clean Architecture kết hợp với React sẽ mang lại các lợi ích sau:
- Dễ bảo trì và mở rộng: các phần như UI, business logic, xử lí api được định nghĩa riêng biệt tại các tầng, giúp cho việc xử lí và xây dựng các thành phần được độc lập, không ảnh hưởng đến toàn bộ hệ thống.
- Không phụ thuộc vào framework: Việc UI chỉ được xử lí riêng biệt tại 1 tầng giúp chuyển đổi sang framework khác trong tương lai trở nên dễ dàng hơn.
- Kiểm thử dễ dàng hơn: có thể dễ dàng viết unit test cho các phần như use case, repository hoặc service mà không cần phụ thuộc vào giao diện người dùng.
3. Xây dựng ứng dụng đơn giản với React + Clean Architecture
Đây là 1 cách tổ chức thư mục khi dùng React kết hợp với Clean Architecture bạn có thể tham khảo:
Cấu trúc thư mục:
src/
├── domain/ # Entities and business rules
│ ├── models/ # Pure TypeScript classes or interfaces
│ └── services/ # Pure business logic
├── application/ # Use cases
│ └── useCases/ # Contains logic orchestrating domain services
├── infrastructure/ # API clients, storage, gateways
│ └── api/ # Axios services or fetch implementations
├── presentation/ # UI layer (React components)
│ ├── components/
│ ├── pages/
│ └── hooks/
├── shared/ # Utilities, types, constants
Tầng Domain – định nghĩa interface User
// domain/models/User.ts
export interface User {
id: string;
name: string;
email: string;
}
Tầng Application – định nghĩa use-case
// application/useCases/GetUser.ts
import { User } from "@/domain/models/User";
import { IUserRepository } from "@/domain/interfaces/IUserRepository";
export class GetUser {
constructor(private userRepo: IUserRepository) {}
async execute(userId: string): Promise<User> {
return await this.userRepo.getById(userId);
}
}
Tầng Infrastructure – định nghĩa repository
// infrastructure/api/UserRepository.ts
import axios from "axios";
import { IUserRepository } from "@/domain/interfaces/IUserRepository";
import { User } from "@/domain/models/User";
export class UserRepository implements IUserRepository {
async getById(userId: string): Promise<User> {
const response = await axios.get(`/api/users/${userId}`);
return response.data;
}
}
Tầng Presentation – tích hợp với thư viện React
// presentation/pages/UserPage.tsx
import React, { useEffect, useState } from "react";
import { User } from "@/domain/models/User";
import { UserRepository } from "@/infrastructure/api/UserRepository";
import { GetUser } from "@/application/useCases/GetUser";
const userRepo = new UserRepository();
const getUserUseCase = new GetUser(userRepo);
export const UserPage: React.FC = () => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
getUserUseCase.execute("1").then(setUser);
}, []);
return (
<div>
<h1>User Profile</h1>
{user ? (
<div>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
) : (
<p>Loading...</p>
)}
</div>
);
};
4. Kết luận
Không phải dự án front-end nào cũng cần áp dụng Clean Architecture. Việc áp dụng Clean Architecture sẽ mang lại lợi ích tối đa trong các trường hợp sau:
- Dự án có quy mô lớn: Khi dự án có nhiều tính năng phức tạp, logic nghiệp vụ dày đặc, hoặc cần duy trì lâu dài, Clean Architecture giúp tổ chức mã nguồn rõ ràng, dễ bảo trì.
- Yêu cầu kiểm thử cao: Nếu dự án cần viết unit test hoặc integration test cho các logic nghiệp vụ, Clean Architecture giúp tách biệt logic để dễ dàng kiểm thử mà không phụ thuộc vào UI hay API.
- Dự án cần thay đổi công nghệ thường xuyên: Nếu bạn dự đoán dự án có thể chuyển đổi framework (ví dụ từ React sang Vue), Clean Architecture giúp logic nghiệp vụ không bị ảnh hưởng bởi sự thay đổi này.
- Đội ngũ lớn: Khi có nhiều lập trình viên cùng làm việc, Clean Architecture cung cấp một cấu trúc rõ ràng, giảm xung đột và dễ dàng phân chia công việc.
Ngược lại, với các dự án nhỏ, đơn giản hoặc chỉ cần phát triển nhanh giao diện, việc áp dụng Clean Architecture có thể làm tăng độ phức tạp không cần thiết.
Link tham khảo: https://dev.to/rubemfsv/clean-architecture-applying-with-react-40h6