Xàm xí về Domain Driven Design - Part 3: Strategic Design - SubDomain - Bounded Context

- 17 mins

Ở các bài trước chúng ta đã phần nào thảo luận về What and Why Domain Driven Design trong việc phát triển các Enterprise System. Trong bài viết này chúng ta sẻ cùng thảo luận về công cụ mà cá nhân mình thấy là quan trọng và thiết yếu nhất của DDD - Strategic Design. Strategic Design thực sự powerful khi phát triển các dự án lớn, phức tạp. Tuy nhiên nếu áp dụng tốt Strategic Design chúng ta cũng sẻ thu được những lợi ích đáng kể đối với các dự án nhỏ dù mặc dù chúng ta không sử dụng bất kì ideas/concepts còn lại trong DDD. Chúng ta sẻ cùng tìm hiểu về approach để xử lí một hệ thống phức tạp, để chia nhỏ hệ thống. Bên cạnh đó phần nào làm rõ các khái niệm như Ubiquitous Language, Bounded Context, Subdomain,….

Như chúng ta đều biết, chia để trị là nghệ thuật của quá trình phát triển phần mềm. Cho dù không có hiểu biết về DDD thì gặp phãi vấn đề lớn chúng ta cũng nghĩ đến việc chia hệ ra thành nhiều phần, tụi mình cũng đã làm như vậy để rồi tiếp cận với Microservices Architecture một cách quán tính. Việc chia hệ thống ra thành các Sub-System với ít kiến thức về Domain Driven Design dẫn đến một hiện trạng là các software/domain concerns không được tách biệt một cách rõ ràng, phân chia trách nhiệm và mối quan hệ giữa chúng cũng diễn ra nhùng nhằn, rối ren. Kiến thức về Strategic Design sẻ phần nào tháo gỡ một số hiện trạng đó.

Với DDD approach chúng ta tiếp cận vấn đề với hai bước chính:

“What?”: Chúng ta sẻ giải quyết domain gì? Gồm các vấn đề nào? Các vấn đề đó đại diện cho khái niệm Problem Space.

“How?”: Khi xác định được vấn đề lớn và chia thành các vấn đề nhỏ rồi, chúng ta tập trung tháo gỡ từng vấn đề. Chúng ta sẻ giải quyết các vấn đề đó như thế nào? Triển khai hiện thực hoá chúng ra sao? Tất cả chúng đại diện cho khái niệm Solution Space.

1. Problem Space và Sub Domain:

Markdowm Image Từ một khía cạnh nào đó chúng ta có thể định nghĩa Domain là các problems mà hệ thống của chúng ta sẻ giải quyết, do đó có thể gọi tập hợp các problems đó là Problem Space.

Để làm cho một Domain trở nên cụ thể và dễ phân tích đánh giá hơn chúng ta thường chia nhỏ Problem Space của Domain đó ra thành các problem nhỏ hơn, chúng có thể được hiểu là các Sub Domain. Sub Domain được chia thành ba loại sau:

Để hiểu hơn về việc chia tách thành các Subdomains, chúng ta hãy nghĩ về việc design một hệ thống E-Commerce. Về cơ bản, một E-Commerce application cần giải quyết các vấn đề sau:

Rõ ràng đó là những vấn đề cơ bản của một E-Commerce application cần giải quyết.

Cái nhìn cá nhân của mình thấy rằng Core Domain của một E-Commerce application cần giải quyết là giúp người mua và người bán hoạt động được dựa trên các chức năng như Product Catalog, Product Listing, Shopping Cart.

Bên cạnh đó có thêm các thành phần Supporting Domain như Rating, Suggestion, Forecasting về cơ bản nó không quan trọng bằng các Core Domain tuy nhiên lại bổ trợ cực kì mạnh mẻ cho Core Business của hệ thống. Hệ thống suggestion hoạt động thông minh mang lại trải nghiệm mua sắm tốt cho người dùng. Hệ thống dự báo hoạt động thông minh có thể giúp các nhà cung cấp nhận thức đánh giá được thị trường, đưa ra các quyết định kinh doanh đúng đắn hơn, giảm thiểu rủi ro trong kinh doanh. Do đó các Supporting Sub Domain đó gián tiếp mang lại thành công cho core business.

Ngoài ra còn có một số Generic Sub Domain ví dụ như user Identity, Authorization/Authentication, Notification là những thứ tuy không mang lại giá trị business cho ứng dụng nhưng lại rất cần thiết cho hệ thống.

Một điều đáng chú ý là một Sub Domain có thể thuộc hai loại Sub Domain khác nhau, nếu một marketplace đặt trải nghiệm người mua hàng lên hàng đầu, muốn xây dựng một hệ thống suggestion system nhằm tạo ra sự khác biệt, lợi thế đối với các tổ chức khác thì Suggestion cũng sẻ có thể coi Core Sub Domain.

Như vậy chúng ta có thể thấy rằng Problem Space cuối cùng cũng là các phần của Domain cần được phát triển để tạo nên core Domain. Đồng nghĩa với việc đánh giá, phân tích Problem Space của một domain lớn sẻ liên quan đến việc phân tích các Sub Domain đã hiện hữu hay chưa và sự hiện hữu của các Sub Domain đó có thực sự cần thiết đối với hệ thống hay không. Sub Domain cho phép chúng ta có cái nhìn vừa bao quát vừa chi tiết các thành phần vấn đề khác nhau của Domain lớn, do đó Sub Domains là một công cụ rất hữu ích trong việc đánh giá, phân tích Problem Space.

Chúng ta đã phần nào rõ ràng các khái niệm về Problem Space và SubDomain. Vậy làm sao để tiếp cận một dự án phức tạp và lèo lái dự án đi đúng hướng? Chúng ta phãi trả lời các câu hỏi sau:

Markdowm Image

Một khi đã xác định rõ ràng được tầm nhìn và mục tiêu chiến lược của Core Domain và các thành phần cần thiết để hỗ trợ, bổ trợ cho Core Domain, chúng ta sẻ có được chiến lượt tốt nhằm tập trung ưu tiên nguồn lực, sức mạnh, tầm nhìn, bí quyết để phát triển Core Domain. Đồng thời đảm bảo rằng tất cả các bên liên quan trong hệ thống có được sự liên kết chặc chẻ và cam kết hợp tác dựa trên một tầm nhìn chung. Không quá lang mang bởi những thành phần không quan trọng nhưng lại chiếm nhiều effort. Các team ở supporting domain cần nhận thức được mình đang làm gì, biết mình đang phục vụ core domain như thế nào, đóng góp ra sao…..

2. Solution Space và Bounded Context:

Markdowm Image

Chúng ta đã xác định Problem Space với các Sub Domain được chia nhỏ, ứng với từng Sub Domain chúng ta sẻ có một hoặc nhiều Solution/Bounded Context để giải quyết nó. Tập hợp chúng gọi là Solution Space.

Mình tạm định nghĩa có phần chưa hoàn chỉnh rằng Solution Space là nơi các vấn đề được giải quyết trong thực tế và Bounded Context là mỗi câu trả lời cho mỗi problem trong Problem Space, là một giải pháp cụ thể, một quan điểm hiện thực hóa, được sử dụng để hiện thực hóa một giải pháp.

Bên cạnh đó chúng ta cũng có thể hình dung rằng mỗi một Bounded Context xác định cách nhìn nhận về một phần của domain business. Một thành phần business có thể có mặt ở nhiều nơi trong một hệ thống tuy nhiên tại mỗi khu vực, mỗi context của hệ thống có thể nhìn nhận thành phần đó một cách khác nhau đó cũng chính là nguyên nhân vì sao họ gọi đó là Bounded Context.

Theo lẻ thông thường, chúng ta luôn có một quan hệ 1-1 lí tưởng cho một câu hỏi và một câu trả lời, do đó để đơn giản hoá chúng ta nên cố gắng chia các Subdomain và Bounded Context sao cho chúng luôn có sự liên kết 1-1 giữa một Subdomain và một Bounded Context.

Markdowm Image

Tuy nhiên trong thực tế ta nên linh động trong việc define các Subdomain và Bounded Context cho hợp lí. Một hệ thống phức tạp có rất ít Domain nhỏ và đơn giản, khi mà chỉ có một Ubiquitous Language và một model duy nhất biểu diễn mọi thứ về một Sub Domain, đồng thời luôn có một liên kết đẹp đẻ 1-1 giữa Sub Domain và Bounded Context như vậy.

Các business rule thường chống chéo, conflict, rối rắm rất nhiều. Cũng là một thuật ngữ nhưng có thể mang nhiều nghĩa khác nhau ở các context khác nhau, và cũng có thể hai từ khác nhau như lại cùng mang một ý nghĩa ở các context khác nhau.

Markdowm Image Markdowm Image

Thông thường sẻ có nhiều solution cùng phối hợp để giải quyết một problem trong Problem Space tuỳ thuộc vào cách bạn nhìn nhận nó. Mỗi một Bounded Context là một trong nhiều solution để giải quyết một problem, do đó một Sub Domain có thể có nhiều Bounded Context. Bên cạnh đó cũng có những trường hợp vì mối quan hệ giữa các Context quá chặt chẻ hay một nguyên nhân nào đó khiến chúng ta phãi giải quyết hai problem trong cùng một Bounded Context, chẳng hạn như việc quản lí user account và role/permission cùng được đặt trong trong một context là Identity And Access hay việc cung cấp product catalog cho client đồng thời hổ trợ admin quản lí product catalog được đặt trong Product Catalog context.

Markdowm Image

Một khi toàn bộ Domain của một của tổ chức đã được chia ra thành các SubDomain, các Bounded Contexts rồi thì chúng ta chỉ cần tập trung vào một khu vực cụ thể thay vì toàn bộ business domain. Với Problem Space đã xác định ở trên chúng ta có thể cơ bản xắp xếp chúng vào các Bounded Context như sau:

Markdowm Image

Lưu ý rằng Problem Space là sự kết hợp giữa Core Domain, các Supporting Domain và Generic Domain. Khi bạn đã hiểu rõ về Problem Space, bạn sẻ đưa ra được Solution Space. Solution Space sẽ bị ảnh hưởng mạnh mẽ bởi hệ thống, công nghệ hiện có và những hệ thống mới sẻ được tạo ra. Ở đây chúng ta cần phải phân tích về các Bounded Context, do đó hãy cân nhắc những câu hỏi quan trọng sau:

3. Size của Bounded Context:

Xác định độ lớn của một Bounded Context như thế nào là hợp lí? Trong một Bounded Context nên chứa bao nhiêu Modules, Aggregates, loại Event, Services?

Thực sự không có một câu trả lời cho con số chính xác cho câu hỏi trên. Một bouded context cần đủ lớn để thể hiện đầy đủ một Ubiquitous Language trong chính nó.

Các khái niệm không thực sự liên quan đến Core Domain thì nên được cân nhắc mức độ quan trọng mới được đưa vào Ubiquitous Language. Nếu một khái niệm không có trong Ubiquitous Language của bạn, thì không nên đưa nó vào model ngay từ đầu. Nếu một hoặc nhiều khái niệm ngoại lai chen vào hãy loại bỏ chúng ra, chúng có thể thuộc về một Supporting hoặc Generic Subdomain hoặc không thuộc model nào cả.

Hãy cẩn thận để không nhầm lẫn các yếu tố là thành phần thực sự của Core Domain. Model của bạn phải thể hiện sự phong phú của Ubiquitous Language trong context, không để xót thứ gì thiết yếu cũng như không có quá nhiều thứ nhỏ nhặt rối rắm khiến chúng ta khó hình dung được thứ gì là cốt lõi cần tập trung, thứ gì là nhỏ nhặt không đáng đề cao. Các công cụ như Context Map(sẻ giới thiệu sau) có thể giúp chúng ta đánh giá những tiêu chí đó một cách tốt hơn.

Bên cạnh đó cũng sẻ có một số nguyên nhân dẫn đến việc chúng ta tạo ra một Bounded Context với một kích thước sai lầm. Những điều gì có thể dẫn chúng ta tạo ra một Bounded Context có kích thước sai?

4. Conclusion:

Với cá nhân mình đánh giá một số kiến thức về Strategic Design kể trên thực sự rất thiết yếu cho việc design cũng như phát triển Enterprise Application:

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora