2009-04-07 46 views
342

POCO = Plain Old CLR (hoặc tốt hơn: Class) ObjectPOCO vs DTO

DTO = Dữ liệu Chuyển Object

Trong post này có sự khác biệt, nhưng thẳng thắn nhất của các blog tôi đọc mô tả POCO trong cách DTO được định nghĩa: DTO là các thùng chứa dữ liệu đơn giản được sử dụng để di chuyển dữ liệu giữa các lớp của một ứng dụng.

POCO và DTO có giống nhau không?

(ps: nhìn vào great article này về POCO như một lối sống)

+4

"POCO = Đối tượng CLR cũ (hoặc tốt hơn: Lớp)". Vì vậy, các đối tượng của bản chất này trong VB.NET cũng sẽ là POCO, chứ không phải POVO. –

Trả lời

514

Một POCO sau các quy tắc của OOP. Cần (nhưng không phải) có trạng thái . POCO đến từ POJO, được đặt ra bởi Martin Fowler [anecdote here]. Ông đã sử dụng thuật ngữ POJO như một cách để làm cho nó gợi cảm hơn để từ chối việc triển khai EJB của khung công tác nặng nề. POCO nên được sử dụng trong cùng một ngữ cảnh trong .Net. Đừng để các khuôn khổ ra lệnh cho thiết kế của đối tượng của bạn.

Mục đích duy nhất của DTO là chuyển trạng thái và không có hành vi. Hãy xem explanation of a DTO của Martin Fowler để biết ví dụ về việc sử dụng mẫu này.

Đây là sự khác biệt: POCO mô tả một cách tiếp cận để lập trình (tốt cũ lỗi thời đối tượng lập trình hướng), nơi DTO là một mô hình được sử dụng để "truyền dữ liệu" sử dụng các đối tượng.

Mặc dù bạn có thể xử lý POCO như DTO, nhưng bạn có nguy cơ tạo anemic domain model nếu bạn làm như vậy. Ngoài ra, có cấu trúc không phù hợp, vì DTO nên được thiết kế để truyền dữ liệu, không đại diện cho cấu trúc thực sự của miền doanh nghiệp. Kết quả của việc này là DTO có xu hướng phẳng hơn so với miền thực của bạn.

Trong một miền có bất kỳ sự phức tạp hợp lý nào, bạn hầu như luôn tạo ra các POCO miền riêng biệt tốt hơn và dịch chúng sang DTO. DDD (thiết kế định hướng miền) xác định anti-corruption layer (một liên kết khác here, nhưng điều tốt nhất cần làm là buy the book), là cấu trúc tốt giúp phân biệt rõ ràng.

+0

Tôi biết tôi đã tham chiếu Martin Fowler rất nhiều ở đây, nhưng ông đã đặt ra thuật ngữ POJO và viết cuốn sách PoEAA là tài liệu tham khảo chính xác cho DTO. –

+0

Tôi không chắc chắn nếu một DTO không nên có hành vi.Judging theo sơ đồ của Martin Fowler, DTO có thể có hành vi. – Beatles1692

+32

@ Beatles1692, các phương pháp được mô tả là mã tuần tự hóa. Nó có lẽ là quá rộng của một tuyên bố để nói "không có hành vi." Làm thế nào về "không có logic kinh doanh." Mã tuần tự hóa và các công cụ đối tượng cấp thấp như mã băm, bình đẳng và chuỗi ký tự phải được chấp nhận. –

6

Tôi nghĩ rằng DTO có thể là POCO. DTO là nhiều hơn về việc sử dụng đối tượng trong khi POCO có nhiều kiểu dáng của đối tượng hơn (tách rời khỏi các khái niệm kiến ​​trúc).

Một ví dụ trong đó POCO khác với DTO khi bạn nói về POCO bên trong mô hình miền/mô hình logic nghiệp vụ của bạn, đây là đại diện OO tốt đẹp của miền vấn đề của bạn. Bạn có thể sử dụng POCO trong toàn bộ ứng dụng, nhưng điều này có thể có một số tác dụng phụ không mong muốn như rò rỉ kiến ​​thức. Ví dụ, DTO được sử dụng từ Lớp dịch vụ mà giao diện người dùng giao tiếp, DTO là biểu diễn bằng phẳng của dữ liệu và chỉ được sử dụng để cung cấp giao diện người dùng với dữ liệu và liên lạc các thay đổi về lớp dịch vụ. Lớp dịch vụ chịu trách nhiệm ánh xạ cả hai cách của DTO tới các đối tượng miền POCO.

Cập nhật Martin Fowler said rằng phương pháp này là đường nặng cần thực hiện và chỉ nên thực hiện nếu có sự không phù hợp đáng kể giữa lớp miền và giao diện người dùng.

+1

@David Landman, liên kết bạn đưa vào là dành cho mẫu DTO địa phương, là khi DTO được sử dụng cho trạng thái chuyển trong ranh giới hệ thống của bạn. Trong những trường hợp này, bạn nên rất cẩn thận, vì trong hệ thống của bạn, bạn đã có một miền được xác định rõ ràng có thể được chia sẻ. Khi chuyển trạng thái qua các ranh giới hệ thống, DTO khó tránh và khá thích hợp trong mọi trường hợp. –

+0

@Michal Meadows, vâng, liên kết thực sự nói về một tập con khác nhau của các vấn đề. Nhưng tôi nghĩ trong trường hợp chuyển trạng thái qua một ranh giới hệ thống, bạn nên sử dụng một dịch vụ dịch thuật để ánh xạ POCO từ một ngữ cảnh đến POCO từ ngữ cảnh khác. Hay bạn đang nói về giới hạn trên một mức hệ thống? –

0

Trường hợp sử dụng chính cho DTO là trả về dữ liệu từ dịch vụ web. Trong trường hợp này, POCO và DTO là tương đương.Bất kỳ hành vi nào trong POCO sẽ bị loại bỏ khi nó được trả về từ một dịch vụ web, do đó, nó không thực sự quan trọng hay không nó có hành vi.

+5

Tôi nghĩ câu trả lời của bạn xuyên tạc những gì xảy ra một chút. Trong trường hợp của một dịch vụ web, một proxy được tạo ra dựa trên trạng thái tiếp xúc của một đối tượng. Điều này có nghĩa là một DTO được tạo ra riêng biệt với POCO chỉ xảy ra để có cùng trạng thái công khai như POCO. Nó có vẻ tinh tế, nhưng nó quan trọng. Lý do là ngay cả khi proxy giống hệt với bản gốc, nó không thực sự được xây dựng từ cùng một lớp. –

+0

Uh, không. Một người dùng DTO để trả về/nhận dữ liệu giữa các tầng, trong trường hợp này là một dịch vụ web. Một lựa chọn một DTO vì nó chỉ có dữ liệu và không có hành vi. Đúng là lớp proxy cũng có thể là một DTO, và nếu bạn đã sử dụng một lớp POCO thay vào đó, thì một proxy sẽ được tạo ra. Nhưng trong trường hợp này, lớp POCO thực sự là một DTO, vì hành vi của nó sẽ không dịch. Tôi vẫn nói sử dụng DTO vì bạn sẽ không bỏ lỡ hành vi chưa từng tồn tại. –

+0

@John Saunders, Xin lỗi nếu tôi không rõ ràng hơn. Tôi không tranh luận về tính hợp lệ của lập luận của bạn, mà thay vào đó là với ngữ nghĩa của nó. ** Theo quan điểm của bạn: DTO có nghĩa là bảo vệ POCO của bạn khỏi những gì bạn mô tả. Để điều này xảy ra, DTO phải được ánh xạ tới POCO. Trong các giải pháp đơn giản đến vừa phức tạp, điều này có thể là quá mức cần thiết và do đó bạn chính xác. –

2

đây là quy tắc chung: DTO == cái ác và chỉ báo của phần mềm được thiết kế quá mức. POCO == tốt. mô hình 'doanh nghiệp' đã phá hủy bộ não của rất nhiều người trong thế giới Java EE. xin vui lòng không lặp lại những sai lầm trong NET đất.

+7

Bạn có thể xây dựng được không? DTO được yêu cầu khi trả lại dữ liệu từ một dịch vụ web, để tránh việc triển khai và các chi tiết cụ thể về nền tảng trong hợp đồng. –

+1

Có, John DTO được thiết kế cho những gì bạn nói và làm việc tốt. Nhưng tiếc là họ thường được sử dụng khi không cần thiết trong các ứng dụng web cấp đơn và có ít giá trị. – Craig

+8

Tôi nghĩ, @drscroogemcduck, có thể bạn không thích DTO vì chúng được sử dụng như một khu nghỉ mát đầu tiên chứ không phải là phương sách cuối cùng, nhưng chúng vốn không phải là cái ác ... không nhiều hơn các mẫu đơn hoặc nhà máy _infamous_. Cái ác là những kiến ​​trúc sư, những người đẩy các khuôn khổ xuống cổ họng của các nhà phát triển, buộc họ phải tạo ra DTO cho mọi thứ. Đối với những gì họ làm, chuyển dữ liệu, DTO (nếu được thực hiện thận trọng) là hoàn toàn phù hợp. –

43

Đây có thể là không cần thiết cho tôi để đóng góp vì tôi đã tuyên bố vị trí của tôi trong bài viết blog của tôi, nhưng đoạn cuối cùng của loại bài viết của khoản tiền mọi thứ lên:

Vì vậy, trong kết luận, học cách yêu POCO , và chắc chắn rằng bạn không truyền bá bất kỳ thông tin sai lệch nào về nó giống như một DTO. DTO là các thùng chứa dữ liệu đơn giản được sử dụng để di chuyển dữ liệu giữa các lớp của một ứng dụng. POCO là các đối tượng kinh doanh chính thức với một yêu cầu rằng chúng là Persistence Ignorant (không có hoặc lưu các phương thức). Cuối cùng, nếu bạn chưa xem cuốn sách của Jimmy Nilsson, hãy nhặt nó từ các ngăn xếp đại học địa phương của bạn. Nó có các ví dụ trong C# và nó rất tuyệt.

BTW, Patrick Tôi đọc bài viết về POCO dưới dạng Lối sống, và tôi hoàn toàn đồng ý, đó là một bài viết tuyệt vời. Nó thực sự là một phần trong cuốn sách của Jimmy Nilsson mà tôi đề nghị. Tôi không có ý tưởng rằng nó đã có sẵn trực tuyến. Cuốn sách của anh ấy thực sự là nguồn thông tin tốt nhất mà tôi đã tìm thấy trên POCO/DTO/Repository/và các thực hành phát triển DDD khác.

+4

Liên kết tới bài viết blog: http://rlacovara.blogspot.com/2009/03/what-is-difference-between-dto-and-poco.html –

25

POCO chỉ đơn giản là một đối tượng không phụ thuộc vào khung bên ngoài. Nó là đồng bằng.

Cho dù POCO có hành vi hay không là không quan trọng.

Một DTO lẽ POCO như thể một đối tượng tên miền (mà thường sẽ giàu hành vi)

thường DTOs có nhiều khả năng mất phụ thuộc vào khung bên ngoài (ví dụ như các thuộc tính) cho các mục đích serialization như thường họ lối ra vào ranh giới của một hệ thống.

Trong kiến ​​trúc kiểu Onion điển hình (thường được sử dụng trong cách tiếp cận DDD rộng) lớp miền được đặt ở giữa và do đó đối tượng của nó không nên ở điểm này có phụ thuộc bên ngoài lớp đó.

-11

Thậm chí không gọi chúng là DTO. Chúng được gọi là Mô hình .... Thời gian. Mô hình không bao giờ có hành vi. Tôi không biết những người đã đưa ra DTO hạn câm này nhưng nó phải là một điều NET. Là tất cả tôi có thể tìm. Hãy suy nghĩ của các mô hình xem trong MVC, điều tương tự ** đập, các mô hình được sử dụng để chuyển trạng thái giữa các lớp máy chủ bên hoặc trong thời gian dây, họ là tất cả các mô hình. Thuộc tính với dữ liệu. Đây là những mô hình bạn vượt qua ove dây. Mô hình, Mô hình Mô hình. Đó là nó.

Tôi muốn thuật ngữ ngu ngốc DTO sẽ biến mất khỏi vốn từ vựng của chúng tôi.

+0

Tôi không biết bạn có ý tưởng này ở đâu mà các mô hình không bao giờ có hành vi. Làm thế nào để bạn mô hình bất cứ điều gì khác hơn là CRUD mà không có hành vi mô hình hóa? Ngay cả ViewModels cũng có hành vi trong nhiều trường hợp, đặc biệt là trong các ứng dụng MVVM. DTO là một thuật ngữ hữu ích vì nó mô tả chính xác mục đích; để chuyển dữ liệu. – Gerald

+4

bị từ chối vì thực tế không chính xác và đối với thái độ không tự chủ. – joedotnot

+0

Vô nghĩa. Các mô hình phải là các vùng chứa ngu ngốc. Không có DTO, đó là một thuật ngữ được tạo thành MS. Bạn chuyển các mô hình giữa các tên miền, dịch vụ và ứng dụng. Giai đoạn. DTO là một sự lãng phí thời hạn không cần thiết và chỉ gây nhầm lẫn nhiều thứ hơn. Mô hình, Mô hình và nhiều Mô hình khác. Mô hình có thể có hoặc không có hành vi. Xem mô hình không nên. Hành vi đó phải ở dạng BL chứ không phải trong lớp Mô hình. – PositiveGuy

0

lớp DTO được sử dụng để serialize/dữ liệu deserialize từ các nguồn khác nhau!.Khi bạn muốn deserialize một đối tượng từ một nguồn, không quan trọng những gì nguồn bên ngoài nó là: dịch vụ, tập tin, cơ sở dữ liệu vv bạn có thể chỉ muốn sử dụng một số phần đó nhưng bạn muốn một cách dễ dàng để deserialize dữ liệu đó vật. sau đó bạn sao chép dữ liệu đó vào XModel bạn muốn sử dụng. Trình nối tiếp là một công nghệ đẹp để tải các đối tượng DTO. Tại sao? bạn chỉ cần một hàm để nạp (deserialize) đối tượng.