Aggregate root là gì
Lời giới thiệu Show Chào các bạn! Sau hơn 1 năm làm việc với DDD, tôi thấy DDD thật là một tư duy mới về cách xây dựng phần mềm. Nhận thấy phương pháp thiết kế này còn khá mới mẻ ở Việt nam, nên tôi xin chia sẻ tổng hợp cơ bản về DDD dành người quan tâm. Bạn có thể là developer, SQA, managers, PO.. miễn là bạn liên quan đến phát triển xây dựng hệ thống phức tạp thì DDD đều có thể cho bạn những gợi ý hữu ích. Do kiến thức còn hạn hẹp cũng như nhiều góc nhìn chủ quan có thể thiếu sót, mong nhận được góp ý của các bạn để bài viết được bổ xung hoàn thiện hơn. 1. DDD là gìDomain-driven design (DDD) là một cách tiếp cận cho phát triển các phần mềm phức tạp; sự phức tạp ở đây là do nghiệp vụ của lĩnh vực kinh doanh (domain business). Cách tiếp cận của DDD là kết nối chặt chẽ việc cài đặt phần mềm với sự tiến hoá của mô hình kinh doanh: – Dự án đặt sự chú trọng nhiều cho phần nghiệp vụ chính (core domain) và các logic nghiệp vụ liên quan. – Mô hình hoá của nghiệp vụ là trọng tâm, nền tảng cho mọi cài đặt phần mềm. – Tăng cường cộng tác giữa nhóm kỹ thuật( developers) và các chuyên gia nghiệp vụ (domain expert) để xây dựng một mô hình tốt giúp xác định và giải quyết hiệu quả bài toán. wiki DDD được tác giả Eric Evan đưa ra sau kinh nghiệm khoảng 20 năm tham gia phát triển phần mềm, xây dựng những ứng dụng lớn cho giới tài chính, ngân hàng, bảo hiểm, giao vận quốc tế.. Dựa trên kinh nghiệm thực tiễn, những best practices tích luỹ được, ông đề xuất một phương pháp tiếp cận mới để xây dựng những phần mềm có nghiệp vụ phức tạp mà nhóm phát triển sẽ gặp rất nhiều khó khăn để làm chủ, quản lý rủi ro, phát triển và duy tu lâu dài. Phương pháp của ông được tổng hợp trong cuốn sách xanh nổi tiếng ” Domain Driven design – tackling complexity in the heart of software” từ 2003. Và Phương pháp đã nhanh chóng nhận được sự tán dương của cộng đồng, ngày càng được phát triển và áp dụng. 1.2 Use caseTại Septeni-Technology: từ nhu cầu phát triển những sản phẩm toàn cầu, chất lượng cao, dễ bảo trì, mở rộng đòi hỏi thống nhất một phương pháp luận phát triển dự án trong công ty, DDD đã được lựa chọn bởi CTO từ Nhật bản và yêu cầu trở thành một trong những nền tảng phát triển của Septeni Technology. Tất cả nhân viên của Septeni Technology đều cần có kiến thức về DDD dù ở các cấp độ khác nhau; DDD cũng hoàn toàn tương thích với SCRUM và yêu cầu cả đội dự án gồm developer, SQA, PO đều cần hiểu. 2. Nền tảng cơ bản của DDDYêu cầu đầu tiên của cách tiếp cận DDD là Ngôn ngữ Chung (UL). DDD nhấn mạnh sự cộng tác, không bó hẹp giữa các lập trình viên với nhau, do đó những người liên quan phải có khả năng trao đổi để cùng hiểu một vấn đề nghiệp vụ. Thực tế chỉ ra rằng các từ vựng “chuyên nghành” rất dễ bị hiểu sai với người ngoài nghành, thậm chí cùng một thuật ngữ khác nhau theo các vai trò khác nhau, định nghĩa cũng có thể khác nhau. ** Ví dụ ** thực tế trong dự án gần đây, nhóm tôi có nhận được yêu cầu về quản lý các dự án cho khách hàng. Và khi thảo luận team tưởng tượng rằng dự án sẽ có các thuộc tính bắt đầu, kết thúc, giá thành, nhân viên, rồi để hoàn thành sẽ có nhiều nhiệm vụ gán cho các thành viên trong đội. Nhóm tưởng tượng đến những trello, jira, dotproject. Nhưng sau này khi nhận được sample từ khách hàng mới nhận ra Project chỉ tương đương với một bản ghi exel tương ứng với một code từ hoá đơn gán cho một người phụ trách. Vậy làm thế nào để có ngôn ngữ chung để ai tham gia dự án cũng thống nhất một cách hiểu, có thể chia sẻ với nhân viên kinh doanh hay nhân viên kỹ thuật. Evan gợi ý rằng nó là tài liệu để mọi người cùng hiểu. Ví dụ khi phân tích về một hệ thống quảng cáo , qua trao đổi, nhà phân tích thấy được một số yêu cầu và đưa ra một giản đồ: Cộng thêm đó là một từ điển thuật ngữ dự án, giải thích chi tiết khái niệm các phần tử trong giản đồ. Với tài liệu đơn giản này, ta có thể dễ dàng chia sẻ, confirm hệ thống với các chuyên viên nghiệp vụ như là nhân viên kinh doanh quảng cáo, nhà quản lý, hay thảo luận giữa nhóm dự án, để cùng nhau khai phá ra các vấn đề cốt lõi, sâu sắc hơn . Điều này có vẻ cũng không mới trong phân tích dự án, nhưng với DDD đây là yêu cầu xuyên suốt vòng đời sản phẩm, DDD yêu cầu mô hình phân tích(analysis) và mô hình cài đặt (coding) là một, phản ánh lẫn nhau. 2.2 Thiết kế hướng mô hình (model driven design)Hãy nhớ, DDD yêu cầu sự thông suốt trong xây dựng và cài đặt mô hình . Những nhà phân tích, kiến trúc sư hệ thống khi làm việc với các bên liên quan, các chuyên gia nghiệp vụ(Domain Experts), sẽ dựng lên mô hình, trao đổi và nhận được sự đồng thuận với các Domain Experts. Sau đó họ cần truyền đạt và đảm bảo các nhà phát triển, lập trình cũng thông suốt mô hình dựng lên, đến lượt mình các lập trình viên khi cài đặt cũng phải thể hiện được mô hình qua code, và nếu ai đó phát hiện bất kì điểm bất hợp lý gì, sửa đổi gì cần thiết với mô hình trong quá trình làm việc, đều cần thông báo và nhận được sự đồng thuận của nhóm phát triển, hay lớn hơn là được review và đồng thuận từ DE. Và DDD cung cấp các cấu thành nền tảng( building blocks) cho việc xây dựng mô hình mà mọi người cùng hiểu đó. Nó là “từ vựng” để thiết kế mô hình theo DDD.2.2.1 Các cấu thành cơ bản để xây dựng mô hình trong DDD1. Entity( Thực thể ) dùng để biểu thị các khái niệm mà sự tồn tại của nó liên tục xuyên suốt, dù các thuộc tính có thay đổi. Ví dụ với một hệ thống quản lý nhân sự, đối tượng nhân viên Employee có các thuộc tính như name, age, address, position; thì theo thời gian thì các thuộc tính này đều có thể thay đổi, được cập nhật, tuy nhiên hệ thống vẫn cần nhận diện 1 nhân viên vẫn là nhân viên đó dù đã cập nhật tuổi, vị trí hay địa chỉ cư trú, hay cả tên cho anh ta trong hoạt động lưu vết cho 1 cá nhân. Vậy Employee cần được xác định là 1 entity.
2. Value Object Vâng dịch thô thì nó là loại đối tượng chứa giá trị gì đó ạ, nên Value object chỉ mô tả đặc điểm, thuộc tính của gì đó. Trong ví dụ trên thì name, age, address, hay position đều là khái niệm thuộc loại Value Object; Nếu giá trị của đối tượng này thay đổi thì nó là đối tượng mới, và nếu giá trị 2 value object như nhau thì có thể dùng thay thế cho nhau. Nghĩa là ở dạng đối tượng này trong dự án chúng ta chỉ quan tâm đến giá trị của nó mà thôi. Với việc phân định là Value Object hay Entity, DDD đưa ra những gợi ý hữu ích cho thực hành như với Value Object thì seft Validate, còn với Entity thì nên dùng Specification patterns.. 3. Service (Dịch vụ) Khi mô hình hóa bài toán thực tế ta cần biểu diễn thực tiễn qua các khái niệm, nhưng Value Object hay Entity thì không đủ, ví dụ để biểu diễn các operations, business policy, process. Ở đây chúng nên được biểu diễn là các service. Thiết kế một service thì nên là stateless, nghĩa là service sau khi phục vụ xong client thì không nên lưu trữ lịch sử giao dịch phục vụ cho kết quả lần tới, xong thì thôi. Một Service trong DDD là một cấu thành quan trọng của model nên cũng cần được làm rõ trong UL. Một vấn đề lưu ý nữa là phân chia nhiệm vụ cho service ở các tầng khác nhau thì khác nhau, ví như service ở infra có thể lo những dịch vụ hạ tầng về liên lạc, thông báo lỗi, truy xuất cơ sở dữ liệu.. không chứa thông tin về nghiệp vụ. Service ở domain phải mang thông tin về xử lý nghiệp vụ, còn Service ở application có thể kết hợp gọi service ở domain và kết hợp xử lý lỗi, cảnh báo lỗi từ Infra cung cấp, để hoàn thành một business use cases. 4. Module Một model lớn có thể chia thành các module, giống như một cuốn sách thì có nhiều chương. Tên module cần nằm trong UL. Với việc sử dụng Entity, Value Object, Service, Module như những thành phần chính kiến tạo nên model, ta thấy rằng Model driven design được nhắc đến trong DDD khá gần với Object Oriented Design, nhưng không giới hạn. Trong ứng dụng phần mềm, các đối tượng domain object liên tục được tạo ra, biến đổi, lưu lại, nên có vòng đời (Life cycle). DDD cung cấp các khái niệm: 5. Aggregate hình tượng của aggregate được biểu diễn như một chùm nho, nhiều quả nho chung trên 1 cuống nho nối với thân cây nho. Aggregate đảm bảo tính nhất quán của mọi thay đổi đối với phần tử trong nó. Về cấu tạo Aggregate có một đối tượng root là một entity là đối tượng duy nhất tham chiếu ra bên ngoài. VD trực quan về Aggregate thì Car là aggrate của tire (bánh xe), wheel(vô lăng).. 6. Factory khi việc khởi tạo một Entity hay Value Object phức tạp, bạn hãy ủy nhiệm cho một Factory. Giống như việc tạo ra 1 chiếc xe phụ thuộc vào hàng trăm linh kiện thì bạn cứ ủy quyền cho nhà máy sản xuất rằng làm cho tôi một chiếc xe mui trần, màu xanh, 4 chỗ thay vì nhập về hàng trăm linh kiện và tự lắp ráp. 7. Repository là kho chứa cho bạn lấy ra hay lưu lại các aggregate. Repository là khái niệm thuộc tầng domain không quan tâm đến kỹ thuật, phương tiện lưu trữ(memory hay db..). Cụ thể việc lưu trữ đến đâu do tầng Infra đảm nhiệm, có thể là một ORM để lưu vào Database. Hình minh họa cho Repository là bà thủ thư, bạn đến thư viện nhận và trả sách qua bà thủ thư. 3. Kiến trúc ứng dụng dùng DDDCác lập trình viên có thể quen với kiến trúc MVC. Nhưng trong sách xanh có nói, đó là những kiến trúc “ông nội” của DDD. Về mặt kiến trúc DDD đề ra việc phân chia làm 4 tầng logic như sau: Evan có giới thiệu khá chi tiết về mô hình 4 tầng trong sách của mình kèm ví dụ tham khảo link ở cuối bài. Ngoài ra hiện cộng đồng DDD cũng đề xuất kiến trúc hiện đại có thể dùng với DDD là Hexagonal Architecture hay Port and adapter. Hi vọng có dịp được chia sẽ sâu về kiến trúc. Trên đây là một số kiến thức cơ sở về DDD để xây dựng mô hình. Phần tiếp theo của DDD cung cấp các hướng dẫn khi phát triển dự án, từng bước hoàn thiện mô hình, xây dựng những ứng dụng lớn. Ở đó DDD đưa ra những gợi ý thiết thực cho quá trình phát triển với các best practices về: – Tái cấu trúc liên tục – Duy trì tính toàn vẹn của mô hình Xin được cùng thảo luận với các bạn trong bài viết tiếp theo. 4. Vài kinh nghiệm với DDD
Một điều tôi thấy tuyệt vời là sự tương thích hoàn toàn của DDD với các phương pháp, công cụ phát triển sản phẩm hiện đại. Tính agility của DDD. DDD và SCRUM nhấn mạnh đến sự tương tác, phản hồi, cải tiến liên tục. Khác với Warterfall, khi giả định của chúng ta từng bước hoàn thành từ trên xuống dưới. Nghĩa là yêu cầu đã đc phân tích đầy đủ và kĩ lưỡng rồi thiết kế hoàn chỉnh rồi lập trình theo thiết kế có sẳn, rồi kiểm thử để đảm bảo cài đặt như đặc tả. Ở SCRUM, Ngay trong một Sprint ngắn, hay thậm chí ở Daily meeting khi cài đặt, nhà phát triển có thể nhanh chóng chia sẻ về một cập nhật cho mô hình, nhận sự phản hồi của nhóm , thông báo với PO.. DDD cũng hướng nhóm SCRUM đến mô hình business ngay từ đầu để mường tượng về sự tiến hoá trong tương lai, khi yêu cầu phát triển là chưa xác định. Việc của nhóm phát triển là liên tục cài đặt và cập nhật mô hình để đạt được sự thông suốt, đúng đắn, qua đó việc phát triển phần mềm không phải là công việc khô khan mà giúp thu lượm được nhiều những kiến thức thực tế kinh doanh. Ngoài ra, DDD cũng nhắc đến CI như là công cụ cần thiết cho automation test, auto deployment, hỗ trợ tích cực cho sự tiến hoá của sản phẩm phần mềm. 5. Tài liệu tham khảo
|