Đối tượng Giá trị so với Thực thể (Thiết kế theo hướng miền)


90

Tôi vừa mới bắt đầu đọc DDD. Tôi không thể hiểu hoàn toàn khái niệm về các đối tượng Thực thể và Giá trị. Ai đó có thể giải thích các vấn đề (khả năng bảo trì, hiệu suất, v.v.) mà một hệ thống có thể gặp phải khi một đối tượng Giá trị được thiết kế như một đối tượng Thực thể không? Ví dụ sẽ rất tuyệt ...


2
Ở đây tôi đã viết một danh sách (IMO) đầy đủ về sự khác biệt giữa hai: enterprisecraftsmanship.com/2016/01/11/…
Vladimir

Câu trả lời:


107

Giảm xuống sự phân biệt cơ bản, bản sắc quan trọng đối với các thực thể, nhưng không quan trọng đối với các đối tượng giá trị. Ví dụ: Tên của ai đó là một đối tượng giá trị. Thực thể Khách hàng có thể bao gồm Tên khách hàng (đối tượng giá trị), Danh sách <Đơn hàng> Danh sách đặt hàng (Danh sách các thực thể) và có thể là Địa chỉ mặc định (thường là một đối tượng giá trị). Thực thể khách hàng sẽ có một ID và mỗi đơn đặt hàng sẽ có một ID, nhưng Tên thì không; nói chung, trong mô hình đối tượng, danh tính của một Địa chỉ có thể không quan trọng.

Đối tượng giá trị thường có thể được biểu diễn dưới dạng các đối tượng bất biến; Việc thay đổi một thuộc tính của một đối tượng giá trị về cơ bản sẽ phá hủy đối tượng cũ và tạo ra một đối tượng mới, bởi vì bạn không quan tâm đến danh tính như với nội dung. Đúng ra, phương thức đối tượng Equals trên Name sẽ trả về "true" miễn là thuộc tính của đối tượng giống với thuộc tính của đối tượng khác.

Tuy nhiên, việc thay đổi một số thuộc tính của một thực thể như Khách hàng không phá hủy khách hàng; một thực thể Khách hàng thường có thể thay đổi. Danh tính vẫn như cũ (ít nhất một khi đối tượng đã được duy trì).

Bạn có thể tạo ra các đối tượng giá trị mà không nhận ra nó; bất cứ khi nào bạn đại diện cho một số khía cạnh của Thực thể bằng cách tạo một lớp chi tiết, bạn đã có một đối tượng giá trị. Ví dụ, một lớp IPAddress, có một số ràng buộc đối với các giá trị hợp lệ nhưng bao gồm các kiểu dữ liệu đơn giản hơn, sẽ là một đối tượng giá trị. Địa chỉ Email có thể là một chuỗi hoặc nó có thể là một đối tượng giá trị với tập hợp các hành vi của riêng nó.

Rất có thể ngay cả các mục có danh tính trong cơ sở dữ liệu của bạn cũng không có danh tính trong mô hình đối tượng của bạn. Nhưng trường hợp đơn giản nhất là sự kết hợp của một số thuộc tính có ý nghĩa với nhau. Có thể bạn không muốn có Customer.FirstName, Customer.LastName, Customer.MiddleInitial và Customer.Title khi bạn có thể gộp chúng lại với nhau thành Customer.Name; chúng có thể sẽ là nhiều trường trong cơ sở dữ liệu của bạn vào thời điểm bạn nghĩ về tính bền bỉ, nhưng mô hình đối tượng của bạn không quan tâm.


Các đối tượng có thể thay đổi không được chia sẻ phù hợp ở đâu? Nếu trong toàn bộ vũ trụ chỉ tồn tại một tham chiếu đến một đối tượng, danh tính của đối tượng sẽ không liên quan ngay cả khi nó có thể thay đổi. Như tôi thấy, một sự vật là một thực thể nếu tồn tại một tham chiếu có thể được sử dụng quan sát một khía cạnh của trạng thái có thể thay đổi mà không cần tham chiếu đó được sử dụng để thay đổi nó . Nếu một thứ không gắn với thế giới bên ngoài và nó là bất biến hoặc chỉ có một tham chiếu đến nó tồn tại ở bất kỳ đâu trong vũ trụ, thì trường hợp trên không thể xảy ra và đó là một giá trị.
supercat

Một cái gì đó như một int[1]có thể là một giá trị có thể thay đổi không được chia sẻ, một giá trị bất biến có thể chia sẻ (nếu không có thứ nào chứa tham chiếu sẽ ghi vào nó) hoặc một thực thể (nếu tồn tại hai hoặc nhiều tham chiếu và một trong số chúng có thể được sử dụng để viết các giá trị có thể được đọc bằng cách sử dụng khác). Thật không may, tôi biết không có hỗ trợ ngôn ngữ trong Java hoặc .NET để ngăn các đối tượng lớp đóng gói các giá trị có thể thay đổi vô tình biến thành các thực thể.
supercat

@supercat, Nếu ý bạn là không có hỗ trợ đơn giản trực tiếp, tôi sẽ đồng ý, nhưng tôi làm điều này vì loại bỏ quyền truy cập công khai vào các trình tạo, chỉ sử dụng các nhà máy tĩnh để tạo các phiên bản mới và hạn chế tất cả quyền truy cập vào trạng thái thông qua các thuộc tính chỉ đọc (Không có trình thiết lập) .
Charles Bretana

35

Bất kỳ đối tượng nào được xác định chung bởi tất cả các thuộc tính của nó đều là đối tượng giá trị. Nếu bất kỳ thuộc tính nào thay đổi, bạn có một phiên bản mới của đối tượng giá trị. Đây là lý do tại sao các đối tượng giá trị được định nghĩa là bất biến.

Nếu đối tượng không được xác định đầy đủ bởi tất cả các thuộc tính của nó thì có một tập con các thuộc tính tạo nên danh tính của đối tượng. Các thuộc tính còn lại có thể thay đổi mà không cần xác định lại đối tượng. Loại đối tượng này không thể được xác định tại bất biến.

Một cách đơn giản hơn để phân biệt là nghĩ về các đối tượng giá trị là dữ liệu tĩnh sẽ không bao giờ thay đổi và các thực thể là dữ liệu phát triển trong ứng dụng của bạn.


7

Các loại giá trị:

  • Loại giá trị không tự tồn tại mà phụ thuộc vào các loại Đối tượng.
  • Đối tượng Kiểu Giá trị thuộc về Đối tượng Kiểu Thực thể.
  • Tuổi thọ của cá thể kiểu giá trị bị ràng buộc bởi tuổi thọ của cá thể thực thể sở hữu.
  • Ba loại giá trị: Cơ bản (kiểu dữ liệu nguyên thủy), Tổng hợp (Địa chỉ) và Bộ sưu tập (Bản đồ, Danh sách, Mảng)

Thực thể:

  • Các loại thực thể có thể tự tồn tại (Danh tính)
  • Một thực thể có vòng đời riêng của nó. Nó có thể tồn tại độc lập với bất kỳ thực thể nào khác.
  • Ví dụ: Con người, Tổ chức, Cao đẳng, Di động, Nhà riêng, v.v .. mọi đối tượng đều có bản sắc riêng

Không liên quan đến DDD :(
HydTechie

6

Tôi không biết liệu điều sau có đúng không, nhưng tôi sẽ nói rằng trong trường hợp đối tượng Địa chỉ, chúng tôi muốn sử dụng nó làm Đối tượng giá trị thay vì Đối tượng vì các thay đổi đối với thực thể sẽ được phản ánh trên tất cả các đối tượng được liên kết ( một người chẳng hạn).

Trong trường hợp này: Bạn đang sống trong nhà của bạn với một số người khác. Nếu chúng ta sử dụng Thực thể cho Địa chỉ, tôi sẽ tranh luận rằng sẽ có một Địa chỉ duy nhất mà tất cả các đối tượng Người liên kết đến. Nếu một người chuyển ra ngoài, bạn muốn cập nhật địa chỉ của người đó. Nếu bạn cập nhật các thuộc tính của Thực thể địa chỉ, tất cả mọi người sẽ có một địa chỉ khác. Trong trường hợp Đối tượng giá trị, chúng tôi sẽ không thể chỉnh sửa Địa chỉ (vì nó là bất biến) và chúng tôi sẽ buộc phải cung cấp Địa chỉ mới cho Người đó.

Điều này nghe có đúng không? Tôi phải nói rằng tôi cũng vẫn còn bối rối về sự khác biệt này, sau khi đọc cuốn sách DDD.

Tiến thêm một bước nữa, điều này sẽ được mô hình hóa như thế nào trong cơ sở dữ liệu? Bạn có tất cả các thuộc tính của đối tượng Địa chỉ dưới dạng các cột trong bảng Người hay bạn sẽ tạo một bảng Địa chỉ riêng biệt cũng sẽ có một số nhận dạng duy nhất? Trong trường hợp thứ hai, những người sống trong cùng một ngôi nhà sẽ có một phiên bản khác nhau của đối tượng Địa chỉ, nhưng những đối tượng đó sẽ giống nhau ngoại trừ thuộc tính ID của họ.


1
"Hãy xem trường hợp này: Bạn đang sống trong nhà của mình với một số người khác. Nếu chúng tôi sử dụng Đối tượng cho Địa chỉ, tôi sẽ tranh luận rằng sẽ có một Địa chỉ duy nhất mà tất cả các đối tượng Người liên kết đến". Tôi nghĩ rằng mỗi người trong số những người đó đều có phiên bản Địa chỉ riêng, nhưng họ chỉ tình cờ bằng nhau (giống như mỗi người trong số họ có thể có tờ tiền 5 đô la, nhưng điều đó không có nghĩa là nó là cùng một tờ tiền)
Prokurors

"nhưng điều đó không có nghĩa là nó là cùng một tờ tiền" - Tôi đoán điều này phụ thuộc vào việc người ta gán hay không thêm các thuộc tính cho tờ tiền (ví dụ: ngày phát hành, vị trí vật lý trong không gian, v.v.); nếu không chúng sẽ giống nhau. Và tôi đoán đối với phần mềm cũng vậy: Địa chỉ giống nhau hay không tùy thuộc vào thuộc tính chúng ta cần / muốn xem xét.
adrhc

4

địa chỉ có thể là thực thể hoặc đối tượng giá trị phụ thuộc vào quá trình busiess. đối tượng địa chỉ có thể là thực thể trong ứng dụng dịch vụ chuyển phát nhanh nhưng địa chỉ có thể là đối tượng giá trị trong một số ứng dụng khác. trong vấn đề nhận dạng ứng dụng chuyển phát nhanh cho đối tượng địa chỉ


2

Tôi đã hỏi về điều này trong một chủ đề khác và tôi nghĩ rằng tôi vẫn còn bối rối. Tôi có thể đang nhầm lẫn giữa việc cân nhắc hiệu suất với mô hình dữ liệu. Trong ứng dụng Lập danh mục của chúng tôi, Khách hàng không thay đổi cho đến khi cần. Điều đó nghe có vẻ ngớ ngẩn - nhưng việc 'đọc' dữ liệu khách hàng nhiều hơn nhiều so với 'ghi' và vì nhiều yêu cầu web đều đánh vào 'nhóm đối tượng đang hoạt động', tôi không muốn tiếp tục tải Khách hàng hết lần này đến lần khác. Vì vậy, tôi đã đi đến một con đường bất biến cho đối tượng Khách hàng - tải đối tượng đó, lưu vào bộ nhớ cache và phân phát cùng một đối tượng cho 99% yêu cầu (đa luồng) muốn gặp Khách hàng. Sau đó, khi khách hàng thay đổi điều gì đó, hãy nhờ một 'người chỉnh sửa' để tạo một Khách hàng mới và vô hiệu hóa khách hàng cũ.

Mối quan tâm của tôi là nếu nhiều luồng nhìn thấy cùng một đối tượng khách hàng và nó có thể thay đổi được, thì khi một luồng bắt đầu thay đổi, nó sẽ xảy ra tình trạng lộn xộn với các luồng khác.

Vấn đề của tôi bây giờ là, 1) điều này có hợp lý không, và 2) cách tốt nhất để thực hiện điều này mà không cần sao chép nhiều mã về các thuộc tính.


1

3 phân biệt giữa EntitiesValue Objects

  • Định danh so với bình đẳng cấu trúc: Các thực thể có định danh, các thực thể giống nhau nếu chúng có cùng một định danh. Các đối tượng giá trị nằm ngoài bàn tay có cấu trúc bằng nhau, chúng ta coi hai đối tượng giá trị bằng nhau khi tất cả các trường đều giống nhau. Các đối tượng giá trị không được có mã định danh.

  • Tính đột biến và tính bất biến: Đối tượng giá trị là cấu trúc dữ liệu bất biến trong khi các thực thể thay đổi trong thời gian tồn tại của chúng.

  • Tuổi thọ: Đối tượng Giá trị nên thuộc về Thực thể


1

Tôi có thể nói trong một câu rất đơn giản, chúng ta có ba loại bình đẳng:

  • Bình đẳng định danh : một lớp có id được lập và hai đối tượng được so sánh với giá trị trường id của chúng.
  • Bình đẳng tham chiếu : nếu một tham chiếu đến hai đối tượng có cùng địa chỉ trong bộ nhớ.
  • Bình đẳng về cấu trúc : hai đối tượng là bằng nhau nếu tất cả các thành viên của chúng được khớp với nhau.

Bình đẳng định danh chỉ đề cập đến Thực thể và bình đẳng cấu trúc chỉ đề cập đến Đối tượng giá trị. Trên thực tế, các Đối tượng Giá trị không có id và chúng ta có thể sử dụng chúng thay thế cho nhau. Ngoài ra các đối tượng giá trị phải là bất biến và các thực thể có thể thay đổi được và các đối tượng giá trị sẽ không có bảng này trong cơ sở dữ liệ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.