Kiến trúc: Clean Architecture (Kiến trúc sạch)
C# Code
// Đây là một snippet giải thích khái niệm và ví dụ cấu trúc.
/*
* CLEAN ARCHITECTURE TRONG UNITY
*
* Clean Architecture là một triết lý thiết kế phần mềm được đề xuất bởi Robert C. Martin (Uncle Bob).
* Mục tiêu chính là tạo ra một hệ thống dễ bảo trì, dễ kiểm thử, và không phụ thuộc vào các
* yếu tố bên ngoài như framework, database, hay UI. Ý tưởng cốt lõi là "Quy tắc Phụ thuộc"
* (The Dependency Rule): các lớp bên trong không được biết gì về các lớp bên ngoài.
*
* Tưởng tượng kiến trúc như những vòng tròn đồng tâm (giống củ hành tây):
* - Vòng trong cùng (Core): Entities - Chứa các đối tượng và quy tắc kinh doanh cốt lõi của game.
* - Vòng tiếp theo: Use Cases (Interactors) - Chứa logic cụ thể của ứng dụng (ví dụ: logic
* khi người chơi tấn công, mua vật phẩm). Lớp này điều phối các Entities.
* - Vòng ngoài hơn: Interface Adapters (Presenters, Controllers) - Chuyển đổi dữ liệu giữa
* Use Cases và lớp ngoài cùng. Ví dụ: Presenter định dạng dữ liệu để View hiển thị.
* - Vòng ngoài cùng: Frameworks & Drivers (UI, Database, Devices) - Là các chi tiết cụ thể:
* Unity Engine, Firebase, UI Toolkit, Input System...
*
* QUY TẮC PHỤ THUỘC: Mọi sự phụ thuộc chỉ được hướng VÀO TRONG.
* - Use Cases không biết gì về UI hay Unity. Nó chỉ biết về Entities.
* - Entities không biết gì về mọi thứ khác.
*
* 1. CẤU TRÚC THƯ MỤC TRONG UNITY (VÍ DỤ):
* /Scripts
* /Core
* /Entities (ví dụ: PlayerStats.cs, Item.cs - class C# thuần)
* /UseCases (ví dụ: PlayerAttackUseCase.cs, IInventoryRepository.cs - interface)
* /Adapters
* /Presenters (ví dụ: PlayerHealthPresenter.cs)
* /Controllers (ví dụ: PlayerInputController.cs)
* /Gateways (ví dụ: FirebaseInventoryRepository.cs - triển khai IInventoryRepository)
* /Frameworks
* /Views (ví dụ: PlayerHealthView.cs - là một MonoBehaviour, gắn vào UI)
* /Services (ví dụ: UnityInputService.cs)
*
* 2. VÍ DỤ LUỒNG HOẠT ĐỘNG (Người chơi nhận sát thương):
* a. UnityInputService (Framework) phát hiện input va chạm.
* b. PlayerInputController (Adapter) nhận sự kiện và gọi Use Case.
* `takeDamageUseCase.Execute(10);`
* c. TakeDamageUseCase (Use Case) nhận yêu cầu, lấy đối tượng PlayerStats (Entity)
* và gọi hàm `playerStats.ReduceHealth(10);`
* d. PlayerStats (Entity) thay đổi giá trị máu.
* e. Use Case phát ra một sự kiện hoặc trả về dữ liệu mới.
* f. PlayerHealthPresenter (Adapter) nhận dữ liệu mới, định dạng nó (ví dụ: "80/100 HP").
* g. PlayerHealthView (Framework/View) nhận dữ liệu đã định dạng từ Presenter và hiển thị
* lên thanh Slider của Unity UI.
*
* 3. LỢI ÍCH:
* - Độc lập với Framework: Logic cốt lõi (Entities, Use Cases) không phụ thuộc vào Unity.
* Bạn có thể lấy logic đó và chạy trên một server hoặc engine khác mà không cần sửa đổi.
* - Dễ kiểm thử (Testable): Bạn có thể viết unit test cho Entities và Use Cases một cách
* dễ dàng mà không cần khởi động Unity Engine.
* - Dễ thay thế: Bạn có thể dễ dàng thay đổi thư viện UI, cách lưu dữ liệu (từ PlayerPrefs
* sang Firebase) mà không ảnh hưởng đến logic game cốt lõi.
*
* 4. KHI NÀO SỬ DỤNG?
* - Clean Architecture phù hợp nhất cho các dự án lớn, phức tạp và có vòng đời dài.
* - Đối với các game nhỏ, prototype, hoặc game jam, việc áp dụng kiến trúc này có thể
* gây ra sự phức tạp không cần thiết (over-engineering).
*/Giới thiệu về Clean Architecture, một triết lý thiết kế phần mềm giúp tách biệt các mối quan tâm thành các lớp riêng biệt (Entities, Use Cases, Adapters, Frameworks), tạo ra một hệ thống độc lập, dễ kiểm thử và bảo trì.