Hơn nhiều năm gần đây, xuất hiện nhiều đề xuất liên quan đến tổ chức code sao cho hợp lý nhất bao gồm Hexagonal, Screaming hay Onion. Các bạn search google để tìm hiểu thêm.
Mặc dù các kiến trúc này đều hơi hơi khác nhau, nhưng chúng rất giống nhau ở chỗ đó là các phần phải tách biệt nhau, càng tách biệt càng tốt. Tất cả đều có những cách giải quyết riêng dựa trên việc chia phần mềm thành các layer. Và mỗi layer phải có những business rule riêng và 1 layer cho các interface.
Nhìn chung, điểm tương đồng là:
Các vòng tròn đại diện cho từng phần. Quy tắc là bạn càng đi sâu vào, level càng tăng lên. Vòng bên ngoài là cơ chế, bên trong là quy tắc.
Dependenncy rule nói là source code chỉ có thể chỉ ngược vào bên trong. Và nó sẽ không biết bất cứ cái gì ở bên ngoài. Cụ thể, tên của function, class, variable hay bất kì entity được khai báo ở vòng tròn ngoài sẽ không được gọi ở vòng tròn trong (bởi vì bên trong có biết gì bên ngoài đâu)
Tương tự, các format của data được sử dụng ở vòng tròn ngoài không nên được sử dụng lại bởi 1 vòng tròn bên trong, đặc biệt là khi những format này được gen bởi 1 framework trong vòng tròn ngoài
Tóm lại, bản chất là không muốn bất cứ cái gì ở ngoài ảnh hưởng đến ở trong.
Entities đóng gói (encapsulate) các business rule của trên toàn bộ app của bạn. Một entity có thể là 1 object với các methods, có thể là 1 tập các data structures, functions. Không quan trọng là gì, miễn là các entities này có thể được sử dụng ở nhiều chỗ khác nhau trong luồng targer app.
Trong 1 ứng dụng đơn giản, thì entities chính là các objects. Chúng đóng gói các rule chung và high-level nhất. Vì chúng ít có khả năng thay đổi nhất khi một cái gì đó bên ngoài thay đổi. Vì nếu mà objects bị ảnh hưởng vì page navigation thì cạn lời. Từ ví dụ về objects, ta cũng đúc kết được là những thay đổi cụ thể trên app sẽ không làm ảnh hưởng đến các entities.
Lớp layer này chứa những business rule cụ thể hơn. Nó đóng gói và thiết lập tất cả use case của hệ thống. Những use case này sắp xếp flow data từ thực thể, và hướng các thực thể này dùng các business rule để giải quyết mục đích của use case.
Layer này không nên bị ảnh hưởng bởi những thay đổi của các yếu tố bên ngoài như database, UI, hoặc bất kỳ framework nào. Layer này được phân tách khỏi những mối quan hệ như thế.
Tuy nhiên, chúng ta lại muốn những thay đổi trong việc hoạt động của ứng dụng sẽ ảnh hưởng đến use case, và tất cả code trong layer này. Nếu chi tiết của một use case thay đổi, thì nhiều đoạn code trong layer này cũng cần thay đổi tương ứng.