Làm thế nào để kết hợp TDD và DDD nghiêm ngặt?


15

TDD là về thiết kế mã, được hướng dẫn bởi các bài kiểm tra.
Do đó, các lớp điển hình thường không được xây dựng trả trước; chúng sẽ xuất hiện một chút qua các bước tái cấu trúc.

Thiết kế hướng tên miền bao gồm rất nhiều mẫu kỹ thuật, xác định các lớp được thiết lập tốt như lớp Ứng dụng, Lớp cơ sở hạ tầng, Lớp Miền, Lớp bền vững.

Để bắt đầu phần mã hóa của dự án DDD từ đầu, làm thế nào để hành xử?
Tôi có nên nghiêm túc để thiết kế xuất hiện từ các thử nghiệm, nghĩa là không tách rời các mối quan tâm (không có lớp) và cấu trúc lại để phù hợp với các mẫu kỹ thuật DDD?

Hoặc tôi nên tạo các lớp trống đó (ứng dụng, thực thể / dịch vụ miền, cơ sở hạ tầng) và để TDD phù hợp với từng lớp một cách độc lập (sử dụng giả để tách biệt giữa các lớp)?


Câu trả lời:


11

Hãy chắc chắn rằng bạn xem lại những nhận xét gần đây của Bác Bob về vai trò của thiết kế trong TDD .

Thiết kế hướng tên miền bao gồm rất nhiều mẫu kỹ thuật, xác định các lớp được thiết lập tốt như lớp Ứng dụng, Lớp cơ sở hạ tầng, Lớp Miền, Lớp bền vững.

Udi Dahan: "Chúa ơi, làm thế nào tôi ghét layering." Anh ấy dành thời gian để thảo luận về nó trong bài nói chuyện về CQRS của mình - nhưng Khác nhau (bắt đầu từ 18m30s)

Tôi sẽ đánh vần câu của bạn hơi khác nhau; "DDD nhận ra rằng có một số mối quan tâm chung cho hầu hết các ứng dụng kinh doanh và các giải pháp cho những mối quan tâm đó có tuổi thọ khác nhau" .

Ví dụ, mối quan tâm về tên miền, như một quy tắc, cần phải linh hoạt - đặc biệt là khi bạn đang tùy chỉnh một giải pháp cho một doanh nghiệp cụ thể. Xét cho cùng, tên miền liên quan đến cách công ty kinh doanh, nghĩa là, cách công ty kiếm tiền và có thể cung cấp các cải tiến kinh doanh nhanh chóng là doanh thu miễn phí.

Mặt khác, có lẽ bạn không cần phải thay đổi thành phần kiên trì thường xuyên. Các giải pháp cơ sở dữ liệu làm việc phát hành cuối cùng có thể cũng sẽ làm việc phát hành này.

Các mối quan tâm ứng dụng là một nơi nào đó ở giữa; chúng có xu hướng ổn định để người dùng không cần phải tìm hiểu một ứng dụng mới với mỗi bản phát hành.

Ngoài ra, có thể có nhiều triển khai để giải quyết bất kỳ mối quan tâm nhất định. Chẳng hạn, ứng dụng có thể chỉ cần một ảnh chụp nhanh về trạng thái hiện tại của nó - chỉ cần lưu tệp vào đĩa là đủ. Và trong vài lần lặp đầu tiên của bạn, đó cũng có thể là tất cả các tên miền cần. Nhưng cuối cùng cũng xuất hiện một câu chuyện yêu cầu hỗ trợ truy vấn đặc biệt và bạn nhận ra rằng việc cấu hình cơ sở dữ liệu quan hệ sẽ dễ dàng hơn rất nhiều so với thực hiện từ đầu. Và sau đó có một tính năng này sẽ hoạt động tốt hơn trong cơ sở dữ liệu đồ thị.

Trong khi đó, CTO muốn có một phiên bản ứng dụng chạy trên điện thoại của mình; Giám đốc điều hành vừa nghe từ một anh chàng rằng xuất bản API là điều quan trọng.

Ngoài ra, nhóm bán hàng sử dụng một mô hình khác, vì vậy hãy cung cấp cho chúng tôi cùng một ứng dụng, với một mô hình khác. Ồ, nhưng chúng tôi đang đi du lịch rất nhiều, vì vậy phiên bản của chúng tôi cần hoạt động khi chúng tôi ngoại tuyến và đồng bộ hóa sau ...

Nói cách khác, bạn áp dụng các mẫu chiến thuật từ không phải bằng cách triển khai các trình giữ chỗ trống và giả sử rằng chúng sẽ được điền vào sau, nhưng thay vào đó bằng cách nhận ra khi bạn băng qua luồng "Này, đó là mã kiên trì trong mô hình miền của tôi, tôi không được thực hiện tái cấu trúc chưa. "


11

Test Driven Development (TDD) không phải là một thiết kế. Đó là một yêu cầu tác động đến thiết kế của bạn. Giống như bạn được yêu cầu phải an toàn cho chủ đề, đó không phải là một thiết kế. Một lần nữa, đó là một yêu cầu tác động đến thiết kế của bạn.

Nếu bạn vui vẻ bỏ qua tất cả các mối quan tâm thiết kế khác và tuân thủ các quy tắc TDD, đừng đổ lỗi cho TDD khi mã của bạn biến thành tào lao. Nó sẽ là thử nghiệm tào lao nhưng nó sẽ là tào lao.

Một điều tuyệt vời về crap có thể kiểm chứng là đó là crap có thể tái cấu trúc nên đối với một số người là đủ tốt. Chúng tôi sẽ chỉ ưa thích khi cần thiết. Những người khác ghét điều này và đổ lỗi cho TDD cho nó. Không. Đây là việc của bạn.

Thiết kế hướng tên miền (DDD) là việc bạn làm trước chu kỳ tái cấu trúc xanh đỏ của TDD.

DDD là nỗ lực tạo và bảo tồn một không gian trong mã nơi một chuyên gia tên miền, người hầu như không biết gì về các chi tiết của hệ thống, có thể hiểu cách kiểm soát hệ thống. Điều này được thực hiện bằng cách trừu tượng hóa và mô hình hóa một miền vấn đề theo cách quen thuộc.

Một hệ thống DDD có thể có một kiến ​​trúc trông như thế này:

nhập mô tả hình ảnh ở đây

Kiến trúc DDD này có rất nhiều tên: Clean , Onion , Hexagonal , v.v.

Đây là sự mất kết nối mà tôi thấy nhiều người có khi nhìn vào thiết kế này. Đây không phải là cụ thể. Tôi có thể làm theo thiết kế này và không bao giờ viết bất cứ điều gì bạn thấy được sơ đồ ở đây. Tôi thấy những người khác nhấn mạnh rằng phải có một đối tượng ca sử dụng hoặc một lớp thực thể. Những gì chúng là một bộ quy tắc cho bạn biết bạn có thể nói chuyện với ai và làm thế nào.

Đó là nó. Thực hiện theo các quy tắc của thiết kế này và bạn có thể TDD trái tim nhỏ bé của bạn ra ngoài. TDD không quan tâm bạn nói chuyện với ai. Nó quan tâm rằng tất cả mọi thứ làm một cái gì đó có thể được chứng minh là hoạt động hoặc không tại một nút bấm. Không, một cái gì đó ở đâu đó bị phá vỡ. Nó cho bạn biết chính xác những gì bị hỏng.

Vẫn còn mơ hồ? Nhìn vào Controler- Use Case Interactor- Presentersơ đồ ở góc dưới bên phải. Dưới đây là ba điều cụ thể giao tiếp với nhau. Chắc chắn đây là DDD nhưng làm thế nào để bạn thêm TDD ở đây? Chỉ cần chế nhạo những thứ cụ thể. Người trình bày phải được nhận thông tin. Một PresenterMocklớp học sẽ là một cách tốt để kiểm tra xem nó có đạt được những gì bạn mong đợi không. Trao Use Case Interactorcác PresenterMockvà lái xe Use Case Interactornhư thể bạn là người Controllervà bạn có một cách tốt đẹp để thử nghiệm đơn vị sự Use Case Interactorkể từ khi mô hình sẽ cho bạn biết nếu nó nhận được những gì bạn mong đợi nó để có được.

Hãy nhìn vào đó. TDD hài lòng và chúng tôi không cần phải thiết kế DDD. Làm thế nào điều đó xảy ra? Chúng tôi bắt đầu với một thiết kế tách rời tốt.

Nếu bạn sử dụng TDD để điều khiển thiết kế (không chỉ đơn giản là D evelopment), bạn sẽ có được một thiết kế phản ánh nỗ lực bạn bỏ ra. Nếu đó là những gì bạn muốn tốt. Nhưng đó không bao giờ là ý nghĩa của TDD. Điều này cuối cùng thiếu chắc chắn không phải là lỗi của TDD.

TDD không phải là về thiết kế. Nếu bạn phải thay đổi thiết kế để sử dụng TDD, bạn có vấn đề lớn hơn là thử nghiệm.


Tôi chưa bao giờ nói rằng TDD là một thiết kế, nhưng đó là về thiết kế.
Mik378

1
Bác Bob đã bảo bạn thiết kế. Anh ấy đã không nói với bạn "hey nếu bạn kiểm tra công việc, những người quan tâm đến phần còn lại".
candied_orange

1
Như tôi đã nói, chỉ cần làm theo các quy tắc của những người bạn được phép nói chuyện. Kiến trúc sạch sẽ không phải là một cái gì đó để tranh luận về BDUF. Chỉ cần xác định phần nào bạn tham gia và suy nghĩ về ai và cách bạn nên giao tiếp. Nó nhanh nhẹn hơn bạn nghĩ. Sau đó hỏi xem nó có thể kiểm tra được bằng TDD không. Nếu đó không phải là bạn đã làm điều gì đó sai. Nếu đó là tôi hy vọng bạn đã chú ý bởi vì thiết kế tốt không chỉ là thử nghiệm.
candied_orange

6
Ugh ... Tôi thực sự không thể chịu được cách hiểu sai "Thiết kế hướng thử nghiệm". Bạn vẫn phải thiết kế một chút trước khi bắt đầu đập mạnh vào bàn phím, dù bạn có viết bài kiểm tra hay không.
RubberDuck

1
Để trích dẫn chú Bob về điểm chính xác này, "Bạn phải thiết kế thời gian" . Nhấp vào đó và nếu bạn quá nôn nóng để đọc toàn bộ tìm kiếm những từ đó. Bạn sẽ thấy Mr Martin khá kiên quyết rằng TDD không phải là viên đạn ma thuật và bạn phải thiết kế không chỉ mã của mình mà cả các bài kiểm tra của bạn nếu bạn không muốn sống trong một cơ sở mã rất dễ vỡ.
candied_orange

4

TDD đảm bảo mã của bạn có tất cả các trường hợp kiểm tra cần thiết được viết song song với sự phát triển. Điều này không nên ảnh hưởng đến thiết kế cấp cao. Hãy nghĩ về nó nhiều hơn trong các chiến hào làm việc.

DDD là tất cả về thiết kế cấp cao, ngôn ngữ giữa các chuyên gia & kỹ sư tên miền, lập bản đồ ngữ cảnh, v.v ... Đây phải là trình điều khiển của thiết kế cấp cao ứng dụng.

Đây là cả hai giải thích nông của hai phương pháp lập trình mạnh mẽ. Nhưng vào cuối ngày họ thực sự hoàn thành hai điều rất khác nhau.

Bắt đầu với ngôn ngữ DDD và ánh xạ ngữ cảnh sau đó cuối cùng khi bạn viết mã bắt đầu thực hành TDD. Nhưng thực tế TDD không nên ảnh hưởng đến thiết kế cấp cao, nhưng nó sẽ đảm bảo mọi thứ có thể được kiểm tra. Có một chút cảnh báo ở đây.

Tôi nghĩ có thể cần lưu ý: Bạn chỉ nên thực hành DDD nếu ứng dụng đủ phức tạp.


1
Tôi không đồng ý, TDD không phải là về thử nghiệm, mà là về thiết kế.
Mik378

Tôi đang dựa trên tất cả 3 quy tắc của TDD như được mô tả bởi chú Bob.
Matt Oaxaca

Steve Freeman, tác giả của cuốn sách GOOS đã nêu: bạn không nên chỉ định bất kỳ lớp hoặc cơ sở hạ tầng nào trước khi bắt đầu chu trình TDD.
Mik378

Tôi không quen thuộc với cuốn sách đó, nhưng tôi phải không đồng ý. Tôi không muốn TDD định hình biểu đồ DI & class của mình.
Matt Oaxaca

3
@ Mik378: TDD không phải là về thử nghiệm, mà chủ yếu không phải là về thiết kế - thiết kế duy nhất do TDD tạo ra là thiết kế cho khả năng kiểm tra đơn vị. Tất cả các phần khác của thiết kế phải đến từ một nơi khác. Tôi thấy TDD nhiều hơn như là một kỹ thuật thực hiện.
Doc Brown

3

DDD là về thiết kế phần mềm.
TDD là về thiết kế mã.

Trong DDD, "mô hình" đại diện cho sự trừu tượng hóa tên miền, tất cả các kiến ​​thức từ chuyên gia tên miền.

Chúng ta có thể sử dụng TDD cho mô hình thiết kế phần mềm ban đầu. Tên miền có các quy tắc kinh doanh và mô hình miền mà bài kiểm tra viết (lần đầu tiên) phải có màu xanh.

Trong thực tế, chúng ta có thể mã hóa các bài kiểm tra, sau khi thiết kế một mô hình hướng theo miền.
Cuốn sách này "Phát triển phần mềm hướng đối tượng, được hướng dẫn bởi các thử nghiệm" liên kết mua để thực
hiện phương pháp này, với bộ xương đi bộ , kiến trúc hình lục giác và TDD.

Nguồn từ: DDD nhanh chóng - InfoQ


1
đối với tôi phần mềm và mã là điều tương tự
Konrad

1
Nó cũng có thể giống nhau. Tôi đã cố gắng nói: phần mềm như một "giải pháp", "hệ thống", "mức độ cao" và là "triển khai", "mức độ thấp", "chi tiết".
JonyLoscal

Tôi nghĩ rằng điều quan trọng là "đầu tiên chúng tôi thử nghiệm, nhưng chúng tôi cần một bộ xương tối thiểu nơi chúng tôi sẽ bắt đầu thử nghiệm". Phải không
JonyLoscal

1

Tôi có nên nghiêm túc để thiết kế xuất hiện từ các thử nghiệm

Không (Tên miền) Thiết kế theo định nghĩa sẽ xuất hiện từ các yêu cầu miền. Đây là ý tưởng tồi để cho phép mọi thứ khác điều khiển thiết kế của bạn, cho dù đó là bộ kiểm tra, lược đồ cơ sở dữ liệu hay ... (sẽ được tiếp tục)

Hoặc tôi nên tạo các lớp trống đó (ứng dụng, thực thể / dịch vụ miền, cơ sở hạ tầng) và để TDD phù hợp với từng lớp một cách độc lập

. .

Khi nói đến DDD, OOP rơi vào các yêu cầu thể hiện ngắn ở dạng có thể đọc được của con người, tức là một cái gì đó sẽ ít nhiều rõ ràng hơn đối với người không lập trình. Các ngôn ngữ FP được gõ nghiêm ngặt làm một công việc tốt hơn. Tôi khuyên bạn nên đọc một cuốn sách về DDD bằng cách sử dụng lập trình chức năng "Mô hình hóa miền thực hiện chức năng" của Scott Wlaschin

https://pragprog.com/book/swdddf/domain-modeling-ADE-feftal

Bạn không phải sử dụng ngôn ngữ FP để mượn một số ý tưởng từ đó (không phải tất cả chúng đều không may), nhưng nếu bạn thực sự đọc nó thì có lẽ bạn sẽ muốn sử dụng ngôn ngữ chức năng.

Nó cũng sẽ trả lời câu hỏi của bạn về cách TDD phù hợp với hình ảnh DDD. Tóm lại, khi các yêu cầu được mã hóa theo kiểu chức năng, nó sẽ loại bỏ sự cần thiết của số lượng lớn các bài kiểm tra đơn vị vì nó làm cho hầu hết các trạng thái và kịch bản không hợp lệ không thể diễn đạt / không thể biên dịch. Tất nhiên, vẫn có nơi để thử nghiệm tự động trong dự án FP nhưng không có nghĩa là các thử nghiệm sẽ thúc đẩy bất kỳ quyết định thiết kế chính nào.

Để tạo một vòng tròn đầy đủ, hãy quay lại câu hỏi tiêu đề, tức là "Cách kết hợp TDD và DDD nghiêm ngặt?". Câu trả lời rất đơn giản: không có gì để kết hợp / không có xung đột lợi ích. Thiết kế theo yêu cầu, phát triển theo thiết kế (bằng cách viết bài kiểm tra trước nếu bạn thực sự muốn làm TDD)


+1 cho cuốn sách DD DDD và giải thích tổng thể.
Roman Susi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.