Domain Oriented Design (Not another DDD post)
White

Nguyễn Thế Huy viết ngày 07/10/2021

Nghiệp vụ được chia thành các domain, và code của chúng ta thì cũng nên như thế

Có lẽ hơn một lần, bạn đã đọc được đâu đó về Domain Drivent Design (DDD). Trong bài viết này, mình sẽ không bàn luận hay phân tích về DDD (Vì nó quá lớn và có nhiều bài viết trên mạng). Trong bài viết này, mình sẽ nói về một phương án thiết kế đơn giản, hướng Domain (Domain Oriented), và đảm bảo tính scale khi codebase lớn dần lên.

Domain là gì ?

Mình sẽ bắt đầu trước với khái niệm Domain. Domain là một vùng hiểu biết về một nghiệp vụ nhất định nào đó. Ví dụ trong một ứng dụng thương mại điện tử điển hình, chúng ta có thể có các domain như sau

  • Customer: Các nghiệp vụ liên quan đến khách hàng
  • Order: Các nghiệp vụ liên quan đến đơn hàng
  • Payment: Các nghiệp vụ liên quan đến thanh toán

Có nhiều cách đặt tên khác nhau cho domain, ví dụ có người gọi là Services hoặc Modules. Tuy nhiên cách hiểu và đặt tên Domain như trên nhằm mục tiêu cao nhất việc chia tách nghiệp vụ với phần còn lại của ứng dụng (Các cái tên như Services hoặc Modules không phản ánh được đủ rõ ràng).

Tại sao ta cần Domain ?

Hầu hết các framework web hiện nay của chúng ta được triển khai trên mô hình MVC (Model - View - Controller). Vấn đề đặt ra rằng, khách hàng của chúng ta không nói chuyện bằng MVC. Bạn sẽ phải đảm bảo rằng ứng dụng của mình xử lý chính xác các Domain nghiệp vụ, đồng thời giải quyết các vấn đề kỹ thuật thường thấy: expose API, queue job, validation, dependency injection .... Nghiệp vụ sẽ được viết ở đâu ?, Controller ?, Model ?. Làm sao ứng dụng có thể scale khi nghiệp vụ thay đổi mà không tác động đến các phần còn lại ?. Đó là lúc chúng ta cần đến Domain, và thảo luận xem ta sẽ tổ chức Domain của mình như thế nào

Chia tách Domain và Application

Nếu bạn đã quen thuộc với DDD, thông thường chúng ta sẽ có ba lớp (Domain, Application, Infratrucsture). Trong bài viết này, để cho đơn giản, mình sẽ chỉ quan tâm đến Domain và Application. Lớp Application có thể bao gồm nhiều Application độc lập nhỏ hơn, tùy thuộc vào bài toán. Application sẽ chứa những thứ cần thiết để ứng dụng hoạt động như Controllers, Models (Giao tiếp với DB), các Repositories, Middlewares, Requests, ....

Chúng ta sẽ thống nhất hai điều

  1. Domain là nghiệp vụ, và sẽ được sử dụng chung với các Application xuyên suốt ứng dụng.
  2. Các Application chỉ giao tiếp với Domain, không giao tiếp với nhau.

Một Domain có thể được tổ chức như sau:
alt text

Trong Domain sẽ có ba thành phần quan trọng mình muốn nhắc đến ở đây

  1. DataTransferObjects (DTO). DTO và tầm quan trọng của nó đã được mình đề cập tại một bài viết trước đó. Trong mô hình hướng Domain, DTO càng quan trọng. DTO sẽ cấu trúc hóa lại các dữ liệu phi cấu trúc (như một HTTP Request), chuẩn hóa các kiểu dữ liệu để đảm bảo chúng được transfer xuyên suốt ứng dụng của mình.

alt text

Một DTO siêu đơn giản có thể trông như thế này, tất nhiên nó còn thiếu rất nhiều ở việc chuẩn hóa dữ liệu. Ở đây mình build một array thành một đối tượng Product.

  1. Models. Khác với Models ở Application đóng vai trò tương tác trực tiếp với database, trong khi Models ở Domain đại diện cho đối tượng nghiệp vụ.

alt text

Ví dụ một model Domain có thể trông như thế này. Application sẽ sử dụng các model này và các phương thức của nó, trong khi tương tác với Database thông qua các Repositories.

  1. Actions

Actions chứa toàn bộ các bussiness logic của ứng dụng. Đối với DDD, mọi người sẽ thấy nó tương đồng với các Command - Handler. Actions là một phiên bản rút gọn của Pattern này: Bạn sẽ không cần thêm một CommandBus nữa. Tất nhiên, CommandBus sẽ tăng tính flexible cho ứng dụng của bạn, nhưng có lẽ trong bài viết này, Actions là đủ.

Một actions có thể là combine của nhiều hành động, nhiều Actions khác nhau. Ở đây mình có một Actions đơn giản CreateOrUpdateProduct:

alt text

Đối với lớp Application thì đã khá quen thuộc, chúng ta có Controllers, Models, Requests nên có lẽ không cần bàn thêm. Bạn có thể thoải mái tổ chức Application của mình sao cho hợp lý, tùy thuộc vào nhu cầu (Ví dụ thành các modules độc lập như HMVC).

Mình có một controller đơn giản để làm API create hoặc update Sản phẩm như thế này
alt text

Controller chỉ đóng vai trò nhận dữ liệu. Nó sẽ chuyển dữ liệu raw (HTTP Request) sang một DTO, và gọi nghiệp vụ tương ứng của domain lên xử lý, sau đó trả dữ liệu cho client.

Business logic của chúng ta sẽ được độc lập hoàn toàn với ứng dụng, giúp quá trình scale ứng dụng dễ dàng hơn, dễ test và giảm lỗi. Ngoài ra việc áp dụng các Design Pattern vào đây cũng trở nên dễ dàng và đơn giản hơn rất nhiều.

Kết

Cách thiết kế trên có thể chưa phải là tốt nhất. Điều quan trọng rằng, bất cứ khi nào bạn thiết kế một ứng dụng, hãy chia tách và group nó theo hướng business logic, chứ ko phải hướng technical (Vì việc của chúng ta là chuyển business thành code mà :D). Việc này sẽ giúp ích rất nhiều cho việc phát triển ứng dụng sau này của bạn. Cám ơn và hy vọng nhận được nhiều feedback của mọi người :D

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Nguyễn Thế Huy

14 bài viết.
69 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
34 8
Hi cả nhà, đây là bài viết đầu tiên của mình trên Kipalog nên có gì không hay mong các bạn thông cảm :D Realtime là gì ? Như chúng ta đều đã biế...
Nguyễn Thế Huy viết gần 4 năm trước
34 8
White
29 6
Xin chào mọi người :D Trong bài viết này mình sẽ trình bày một cách cơ bản để ứng dụng kỹ thuật Http Live Streaming (HLS) để play video trên web, ...
Nguyễn Thế Huy viết hơn 3 năm trước
29 6
White
27 6
Bài toán Machine Learning và những ứng dụng của nó đang ngày càng trở nên nổi bật trong những năm trở lại đây. Với sự phát triển thần tốc của cấu ...
Nguyễn Thế Huy viết hơn 2 năm trước
27 6
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
14 bài viết.
69 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!