Table of Contents
DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together – @hgraca (herbertograca.com)
Đầu tiên bắt đầu bằng 2 loại kiến trúc: EBI
(Entity – Boundary – Interactor) và Port & Adapters
.
Xem thêm về EBI
ở đây: https://ebi.readthedocs.io/en/latest/structuring.html
Cả hai sẽ giúp phân tách phần code external và interal. Và cả phần nào để kết nối giữa internal và external.
Các block cơ sở
Port & Adapters
Trong kiến trúc này có ba khối cơ bản:
User interface
: bất ký loại giao tiếp người dùng nàoApplication core
: chứa business logic được dùng bởi blockUser interface
.Infrastructure
: kết nối phầnApplication core
đến các công cụ 3rd party.
Tiếp theo bên trong Application core
, ta sẽ cần những tools mà business logic cần dùng. Bao gồm 2 nhóm
Nhóm những thứ “được gọi bởi ứng dụng” dùng pattern Driving adapters
- Database engine
- Search engine
Nhóm những thứ “gửi yêu cầu đến ứng dụng” sẽ dùng pattern Driven adapters
- Web server
- CLI
Các adapter này được tạo ra để fit với điểm bắt đầu trỏ đến Application core. Ở đây gọi là Port
.
Port
trong nhiều ngôn ngữ lập trình, có thể hiểu là interface. Nó chứa không có gì ngoài những đặc tả cách công ty có thể dùng Application core. Nhưng lưu ý là Port
nằm bên trong business logic.
Driving Adapters
Trong thế giới thực driving adapter ở đây có thể là Controller hoặc Console Command. Hàm khởi tạo của các adapter này sẽ được inject các ports mà chúng cần.
Port có thể là : Service
, Repository
hoặc Query
. Hoặc cũng có thể là Command bus, Query bus.
Driven Adapters
Ngược lại với Driving adapter, loại adapter này được hiện thực bằng cách những interface sẽ được inject vào Application Core ở những port đòi hỏi.
Inversion of Control
IoC dùng để chặn việc phụ thuộc lên một tool cụ thể nào đó. Business logic chỉ phụ thuộc lên các Port
. Bằng cách ứng dụng Port & Adapter, ứng dụng hoàn toàn nghịch đảo phụ thuộc vào các Adapters
. Nghĩa là cả Adapter và Application core đều phụ thuộc lên cái ports mà không phụ thuộc lẫn nhau. Duyệt qua , với nhiều lựa chọn phù hợp với mọi sở thích và ngân sách, có thể mua trực tuyến.
Tổ chức bên trong Application Core
Kiến trúc Onion
tiếp cận hướng Domain-Driven Development. Bên trong một ứng dụng enterprise, sẽ có nhiều hơn 2 layers:
- Application Services
- Domain Services
- Domain Model
- Domain Services
Lưu ý: thứ tự phụ thuộc
- Layer trên phụ thuộc layer dưới
- Layer dưới không biết về layer trên
Nghĩa là Application services sẽ phụ thuộc domain services và Domain Model. Domain services sẽ phụ thuộc Domain Model. Và layer dưới sẽ không biết layer trên. Domain Model sẽ không biết Domain Services và Application services.
Vậy bây giờ sẽ đi vào từng tầng bên trong Application core.
Application services
Layer này , bên cạnh việc chứa interface của nó, sẽ bao gồm ports của: ORM, Search engine, messaging.
Nếu ứng dụng CQRS. Layer này sẽ là nơi chứa Handlers của Commands và Queries. Nếu bạn chưa có khái niệm về CQRS, có thể đọc thêm bài viết này: CQRS là gì?
Tóm tắt chức năng của Application services sẽ là:
- Dùng repo để tìm các entities
- Nói cho các entities biết để thực hiện các domain logic
- Dùng các repository để duy trí các entities và thực hiện lưu dữ liệu hiệu quả
Trong ngữ cảnh dùng Command Handlers:
- Chứa logic để thực hiện use case
- Hoặc giữ nhiệm vụ nhận một command và có một trigger đơn giản để đến logic sẵn có trong ứng dụng