Sự khác biệt giữa DTO, VO, POJO, JavaBeans?


584

Đã thấy một số câu hỏi tương tự:

Bạn cũng có thể vui lòng cho tôi biết bối cảnh mà chúng được sử dụng không? Hay mục đích của chúng?


1
POJO không có giới hạn trong khi javabeans đi kèm với các hạn chế được đề cập ở trên
exexzian

Câu trả lời:


848

JavaBeans

JavaBean là một lớp tuân theo các quy ước JavaBeans như được định nghĩa bởi Sun. Wikipedia có một bản tóm tắt khá hay về JavaBeans là gì :

JavaBeans là các thành phần phần mềm có thể tái sử dụng cho Java có thể được thao tác trực quan trong một công cụ xây dựng. Thực tế, chúng là các lớp được viết bằng ngôn ngữ lập trình Java tuân theo một quy ước cụ thể. Chúng được sử dụng để gói gọn nhiều đối tượng thành một đối tượng (bean), do đó chúng có thể được truyền xung quanh dưới dạng một đối tượng bean thay vì nhiều đối tượng riêng lẻ. JavaBean là một Đối tượng Java có khả năng tuần tự hóa, có một hàm tạo rỗng và cho phép truy cập vào các thuộc tính bằng các phương thức getter và setter.

Để hoạt động như một lớp JavaBean, một lớp đối tượng phải tuân theo các quy ước nhất định về đặt tên phương thức, xây dựng và hành vi. Các quy ước này cho phép có các công cụ có thể sử dụng, tái sử dụng, thay thế và kết nối JavaBeans.

Các quy ước bắt buộc là:

  • Lớp phải có một hàm tạo mặc định công khai. Điều này cho phép khởi tạo dễ dàng trong khung chỉnh sửa và kích hoạt.
  • Các thuộc tính lớp phải có thể truy cập được bằng cách sử dụng get, set và các phương thức khác (được gọi là phương thức accessor và phương thức mutator), theo một quy ước đặt tên tiêu chuẩn. Điều này cho phép dễ dàng kiểm tra tự động và cập nhật trạng thái bean trong các khung, nhiều trong số đó bao gồm các trình soạn thảo tùy chỉnh cho các loại thuộc tính khác nhau.
  • Các lớp nên được tuần tự hóa. Điều này cho phép các ứng dụng và khung công tác lưu trữ, lưu trữ và khôi phục trạng thái của bean một cách đáng tin cậy theo cách độc lập với VM và nền tảng.

Do các yêu cầu này được thể hiện chủ yếu dưới dạng các quy ước thay vì thực hiện các giao diện, một số nhà phát triển xem JavaBeans là các Đối tượng Java cũ đơn giản tuân theo các quy ước đặt tên cụ thể.

POJO

Đối tượng Java cũ đơn giản hoặc POJO là thuật ngữ ban đầu được giới thiệu để chỉ định một đối tượng Java đơn giản, không triển khai bất kỳ javax.ejbgiao diện nào , trái ngược với EJB 2.x nặng (đặc biệt là Đậu thực thể, Đậu phiên không trạng thái không phải là IMO xấu). Ngày nay, thuật ngữ này được sử dụng cho bất kỳ đối tượng đơn giản nào không có thêm nội dung. Một lần nữa, Wikipedia thực hiện tốt công việc xác định POJO :

POJO là từ viết tắt của Plain Old Java Object. Tên được sử dụng để nhấn mạnh rằng đối tượng được đề cập là Đối tượng Java thông thường, không phải là đối tượng đặc biệt và đặc biệt không phải là Enterprise JavaBean (đặc biệt là trước EJB 3). Thuật ngữ này được đặt ra bởi Martin Fowler, Rebecca Parsons và Josh MacKenzie vào tháng 9 năm 2000:

"Chúng tôi tự hỏi tại sao mọi người lại chống lại việc sử dụng các vật thể thông thường trong hệ thống của họ và kết luận rằng đó là vì các vật thể đơn giản không có một cái tên lạ mắt. Vì vậy, chúng tôi đã cho chúng một cái, và nó được bắt rất độc đáo."

Thuật ngữ này tiếp tục mô hình các thuật ngữ cũ hơn cho các công nghệ không sử dụng các tính năng mới lạ mắt, chẳng hạn như POTS (Dịch vụ điện thoại cũ đơn giản) trong điện thoại và PODS (Cấu trúc dữ liệu cũ) được xác định trong C ++ nhưng chỉ sử dụng các tính năng ngôn ngữ C, và POD (Tài liệu cũ đơn giản) trong Perl.

Thuật ngữ này rất có thể đã đạt được sự chấp nhận rộng rãi vì nhu cầu về một thuật ngữ phổ biến và dễ hiểu tương phản với các khung đối tượng phức tạp. JavaBean là một POJO có khả năng tuần tự hóa, có hàm tạo không có đối số và cho phép truy cập vào các thuộc tính bằng các phương thức getter và setter. Enterprise JavaBean không phải là một lớp đơn lẻ mà là toàn bộ mô hình thành phần (một lần nữa, EJB 3 làm giảm độ phức tạp của Enterprise JavaBeans).

Khi các thiết kế sử dụng POJO trở nên phổ biến hơn, các hệ thống đã phát sinh mang đến cho POJO một số chức năng được sử dụng trong các khung và có nhiều sự lựa chọn hơn về lĩnh vực chức năng nào thực sự cần thiết. Hibernate và Spring là những ví dụ.

Đối tượng giá trị

Đối tượng giá trị hoặc VO là một đối tượng như java.lang.Integergiữ các giá trị (do đó các đối tượng giá trị). Để có định nghĩa chính thức hơn, tôi thường tham khảo mô tả về Đối tượng giá trị của Martin Fowler :

Trong Mô hình kiến ​​trúc ứng dụng doanh nghiệp, tôi đã mô tả Đối tượng giá trị như một đối tượng nhỏ, chẳng hạn như đối tượng Tiền hoặc phạm vi ngày. Tài sản quan trọng của họ là họ tuân theo ngữ nghĩa giá trị hơn là ngữ nghĩa tham chiếu.

Bạn thường có thể nói với họ vì khái niệm bình đẳng của họ không dựa trên danh tính, thay vào đó hai đối tượng giá trị bằng nhau nếu tất cả các trường của chúng bằng nhau. Mặc dù tất cả các trường đều bằng nhau, bạn không cần so sánh tất cả các trường nếu một tập hợp con là duy nhất - ví dụ mã tiền tệ cho các đối tượng tiền tệ là đủ để kiểm tra sự bằng nhau.

Một heuristic chung là các đối tượng giá trị nên hoàn toàn bất biến. Nếu bạn muốn thay đổi một đối tượng giá trị, bạn nên thay thế đối tượng bằng một đối tượng mới và không được phép cập nhật các giá trị của chính đối tượng giá trị - các đối tượng giá trị có thể cập nhật dẫn đến các vấn đề răng cưa.

Tài liệu J2EE ban đầu đã sử dụng đối tượng giá trị thuật ngữ để mô tả một khái niệm khác, cái mà tôi gọi là Đối tượng truyền dữ liệu . Họ đã thay đổi cách sử dụng và sử dụng thuật ngữ Chuyển đối tượng thay thế.

Bạn có thể tìm thấy một số tài liệu tốt hơn về các đối tượng giá trị trên wiki và bởi Dirk Riehle .

Đối tượng truyền dữ liệu

Đối tượng truyền dữ liệu hoặc DTO là một mẫu (chống) được giới thiệu với EJB. Thay vì thực hiện nhiều cuộc gọi từ xa trên EJB, ý tưởng là đóng gói dữ liệu trong một đối tượng giá trị có thể được truyền qua mạng: Đối tượng truyền dữ liệu. Wikipedia có một định nghĩa đúng đắn về đối tượng truyền dữ liệu :

Đối tượng truyền dữ liệu (DTO), trước đây gọi là đối tượng giá trị hoặc VO, là một mẫu thiết kế được sử dụng để truyền dữ liệu giữa các hệ thống con ứng dụng phần mềm. DTO thường được sử dụng cùng với các đối tượng truy cập dữ liệu để lấy dữ liệu từ cơ sở dữ liệu.

Sự khác biệt giữa các đối tượng truyền dữ liệu và đối tượng kinh doanh hoặc đối tượng truy cập dữ liệu là DTO không có bất kỳ hành vi nào ngoại trừ việc lưu trữ và truy xuất dữ liệu của chính nó (bộ truy cập và bộ biến đổi).

Trong kiến ​​trúc EJB truyền thống, các DTO phục vụ các mục đích kép: đầu tiên, chúng giải quyết vấn đề là các thực thể không được tuần tự hóa; thứ hai, họ ngầm định nghĩa một giai đoạn lắp ráp trong đó tất cả dữ liệu được sử dụng bởi chế độ xem được tìm nạp và sắp xếp vào các DTO trước khi trả lại quyền điều khiển cho tầng trình bày.


Vì vậy, đối với nhiều người, DTO và VO là cùng một thứ (nhưng Fowler sử dụng VO có nghĩa là một cái gì đó khác như chúng ta đã thấy). Hầu hết thời gian, họ tuân theo các quy ước JavaBeans và do đó, JavaBeans cũng vậy. Và tất cả đều là POJO.


1
Vì vậy, nếu tôi có một lớp tiện lợi được tạo chỉ để chuyển dữ liệu không liên quan như lớp này class SomeClass { public String foo;public String bar; }bên trong một lớp có nhiều logic phức tạp, chắc chắn đó không phải là JavaBean, nó không thể là VO vì nó có thể thay đổi, có thể là một DTO? nghĩ rằng nó không được nhắm mục tiêu cho các loại từ xa. Nó có thể được coi là một POJO?
Jaime Hablutzel

3
@ user2601512: Nó vẫn là Bean. : P Không có gì sai khi Bean có hành vi - thực tế, nó được mong đợi khá nhiều. Nếu nó không làm gì khác, về cơ bản nó là DTO.
cHao

7
@xSNRG: Một phần vì nó hạ cấp các đối tượng cho dữ liệu mà các mã khác hoạt động theo. Đó là một bước lùi từ quan điểm OO, nơi các đối tượng hành động và phải chịu trách nhiệm về trạng thái của chính họ. DTO đôi khi là một giải pháp hợp lý nếu bạn thực sự chỉ truyền dữ liệu - do đó tên - nhưng về cơ bản đóng gói đi ra ngoài cửa sổ và bạn thường mất bất kỳ đảm bảo tính hợp lệ / nhất quán nào mà một đối tượng thực có thể cung cấp.
cHao

1
@KumaresanPerumal: Bạn có thể, nếu bạn muốn. Nhưng mô hình này khác với lớp dữ liệu và có các mục tiêu và quy tắc khác nhau. Lớp dữ liệu thường cần mọi thứ được đặt ra và có thể thiết lập tùy ý, và mô hình lý tưởng muốn ẩn dữ liệu và thực thi các bất biến. Bạn muốn sử dụng các đối tượng mô hình để lưu trữ, bạn sẽ phải thỏa hiệp ở bên này hay bên kia.
cHao

1
@KumaresanPerumal: Lớp dữ liệu ở đó để lưu trữ và truy xuất dữ liệu. Để làm điều đó, tất cả nhưng cần truy cập đầy đủ vào bất kỳ đối tượng nào chứa dữ liệu, vì truy xuất có nghĩa là đặt giá trị trong một đối tượng ở đâu đó. Nhưng mô hình quản lý dữ liệu đó trong hệ thống và bị ràng buộc bởi các nguyên tắc OO, như đóng gói - ý tưởng rằng các đối tượng nên duy trì quyền kiểm soát trạng thái bên trong của chúng và không để các mã khác lộn xộn với các bộ phận bên trong của chúng một cách tùy tiện. DTO có thể thu hẹp khoảng cách đó; lớp dữ liệu có thể truy cập chúng theo ý muốn và mô hình không phải hủy bỏ quyền kiểm soát.
cHao

66

DTO vs VO

DTO - Các đối tượng truyền dữ liệu chỉ là các thùng chứa dữ liệu được sử dụng để vận chuyển dữ liệu giữa các lớp và tầng.

  • Nó chủ yếu chứa các thuộc tính. Bạn thậm chí có thể sử dụng các thuộc tính công cộng mà không cần getters và setters.
  • Các đối tượng truyền dữ liệu không chứa bất kỳ logic kinh doanh nào.

Tương tự:
Mẫu đăng ký đơn giản với tên người dùng thuộc tính, mật khẩu và id email.

  • Khi biểu mẫu này được gửi trong tệp RegistrationServlet, bạn sẽ nhận được tất cả các thuộc tính từ lớp xem đến lớp nghiệp vụ nơi bạn chuyển các thuộc tính cho các hạt java và sau đó đến lớp DAO hoặc lớp kiên trì.
  • DTO giúp vận chuyển các thuộc tính từ lớp xem sang lớp nghiệp vụ và cuối cùng đến lớp bền vững.

DTO chủ yếu được sử dụng để truyền dữ liệu qua mạng một cách hiệu quả, thậm chí có thể từ JVM sang JVM khác.

Các DTO thường java.io.Serializable- để truyền dữ liệu qua JVM.

VO - Đối tượng giá trị [1] [2] thể hiện chính nó là một tập hợp dữ liệu cố định và tương tự như một enum Java. Danh tính của Đối tượng Giá trị dựa trên trạng thái của họ chứ không phải dựa trên danh tính đối tượng của họ và là bất biến. Một ví dụ trong thế giới thực sẽ là Color.RED, Color.BLUE, SEX.FEMALE, v.v.

POJO vs JavaBeans

[1] Java-Beanness của POJO là các thuộc tính riêng tư của nó đều được truy cập thông qua các công cụ và setters công khai tuân thủ các quy ước JavaBeans. ví dụ

    private String foo;
    public String getFoo(){...}
    public void setFoo(String foo){...}; 

[2] JavaBeans phải triển khai tuần tự hóa và có hàm tạo không có đối số, trong khi đó trong POJO không có những hạn chế này.


Xin lỗi vì nhận xét rất muộn, nhưng tôi đang tìm hiểu về sự khác biệt giữa họ và tôi có một câu hỏi. Điều gì xảy ra nếu tôi có một lớp Java Bean, nhưng với các phương thức khác như doS Something (). Nó sẽ là loại lớp nào? Trân trọng
jscherman

@srinivas tại sao chúng ta không thể truyền dữ liệu trong đối tượng java DOMAIN hoặc MODEL? Nhưng tôi sử dụng MODEL mà không có DTO. hãy giải thích ngắn gọn cho tôi cảm ơn
Kumaresan Perumal

46

Về cơ bản,

DTO: "Đối tượng truyền dữ liệu" có thể di chuyển giữa các lớp riêng biệt trong kiến ​​trúc phần mềm.

VO: "Đối tượng giá trị" giữ một đối tượng như Integer, Money, v.v.

POJO: Đối tượng Java cũ đơn giản không phải là một đối tượng đặc biệt.

Đậu Java: yêu cầu Java Classphải được tuần tự hóa, có hàm no-argtạo và hàm getter và setter cho từng trường


Những mô tả này hầu hết là sai / không đầy đủ.
cellepo

24

Đậu Java không giống với EJB.

Đặc tả JavaBeans trong Java 1.0 là nỗ lực của Sun để cho phép các đối tượng Java được thao tác trong một IDE trông giống như VB. Có các quy tắc được đặt ra cho các đối tượng đủ điều kiện là "Đậu Java":

  1. Nhà xây dựng mặc định
  2. Getters và setters cho các thành viên dữ liệu riêng tư theo quy ước đặt tên thích hợp
  3. Nối tiếp
  4. Có lẽ những người khác mà tôi đang quên.

EJB đến sau. Họ kết hợp các thành phần phân tán và mô hình giao dịch, chạy trong một thùng chứa quản lý các luồng, gộp, vòng đời và cung cấp dịch vụ. Họ khác xa với Đậu Java.

Các DTO xuất hiện trong bối cảnh Java vì mọi người phát hiện ra rằng thông số EJB 1.0 quá "trò chuyện" với cơ sở dữ liệu. Thay vì tạo một vòng tròn cho mọi thành phần dữ liệu, mọi người sẽ đóng gói chúng thành Đậu Java với số lượng lớn và gửi chúng đi khắp nơi.

POJO là một phản ứng chống lại EJB.


1
Tôi đã sai và tôi muốn xóa tin nhắn của tôi. Cảm ơn đã sửa chữa. Tôi muốn lưu ý rằng ý nghĩa POJO đã thay đổi một thời gian trước đây. Đầu tiên, chúng chỉ được làm bằng tài sản riêng và người truy cập của chúng. Bây giờ, chúng tôi coi POJO là một lớp có chú thích, triển khai và mở rộng các lớp khác, v.v.
sinuhepop

Thế còn VO, như câu hỏi đã hỏi? Đây không phải là Câu trả lời cho đến khi nó trả lời toàn bộ Câu hỏi
cellepo

4

POJO : Đây là một tệp java (lớp) không mở rộng hoặc thực hiện bất kỳ tệp java (lớp) nào khác.

Bean : Đây là một tệp java (lớp) trong đó tất cả các biến là riêng tư, các phương thức là công khai và các getters và setters thích hợp được sử dụng để truy cập các biến.

Lớp học bình thường : Đó là một tệp java (lớp) có thể bao gồm các biến công khai / riêng tư / mặc định / được bảo vệ và có thể hoặc không thể mở rộng hoặc thực hiện một tệp java (lớp) khác.


Thế còn VO, như câu hỏi đã hỏi? Đây không phải là Câu trả lời cho đến khi nó trả lời toàn bộ Câu hỏi
cellepo

1

Nói chuyện đầu tiên về

Lớp bình thường - có nghĩa là bất kỳ lớp nào định nghĩa đó là bình thường trong java, điều đó có nghĩa là bạn tạo ra các loại thuộc tính phương thức khác nhau, v.v.
Bean - Bean không phải là đối tượng của lớp cụ thể đó bằng cách sử dụng bean này mà bạn có thể truy cập lớp java giống như đối tượng..

và sau đó nói về một POJO cuối cùng

POJO - POJO là lớp không có bất kỳ dịch vụ nào, nó chỉ có một hàm tạo mặc định và thuộc tính riêng và các thuộc tính đó để thiết lập một giá trị phương thức setter và getter tương ứng. Đó là dạng ngắn của Object Java Plain.


Thế còn VO, như câu hỏi đã hỏi? Đây không phải là Câu trả lời cho đến khi nó trả lời toàn bộ Câu hỏi
cellepo

1
  • Đối tượng giá trị : Sử dụng khi cần đo sự bằng nhau của các đối tượng dựa trên giá trị của các đối tượng.
  • Đối tượng truyền dữ liệu: Truyền dữ liệu với nhiều thuộc tính trong một lần bắn từ máy khách sang máy chủ trên lớp, để tránh nhiều cuộc gọi đến máy chủ từ xa.
  • Đối tượng Java cũ đơn giản: Nó giống như lớp đơn giản có thuộc tính, hàm tạo không có đối số công khai. Như chúng tôi tuyên bố cho thực thể JPA.

sự khác biệt giữa giá trị-đối tượng-mẫu-và-dữ liệu-truyền-mẫu

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.