Các đối tượng bất biến và DDD đi cùng nhau?


18

Hãy xem xét một hệ thống sử dụng DDD (cũng như: bất kỳ hệ thống nào sử dụng ORM). Điểm thực của bất kỳ hệ thống nào trong thực tế, trong gần như mọi trường hợp sử dụng, sẽ là thao túng các đối tượng miền đó. Mặt khác, không có tác dụng hoặc mục đích thực sự.

Sửa đổi một đối tượng không thay đổi sẽ khiến nó tạo ra một bản ghi mới sau khi đối tượng được duy trì, tạo ra sự phình to trong nguồn dữ liệu (trừ khi bạn xóa các bản ghi trước đó sau khi sửa đổi).

Tôi có thể thấy lợi ích của việc sử dụng các đối tượng bất biến, nhưng theo nghĩa này, tôi không bao giờ thấy trường hợp hữu ích khi sử dụng các đối tượng bất biến. Điều này có sai không?


Câu trả lời:


16

Tính toán bằng cách sử dụng các đối tượng bất biến (như trong lập trình chức năng) không nhất thiết ngụ ý duy trì mọi đối tượng được tạo ra!


Mặc dù vậy, tôi không thấy một trường hợp nào mà kịch bản đó sử dụng các đối tượng bất biến - vì vậy chúng sẽ không có ở đó cho mục đích cụ thể. Tôi có lầm không?
Steven Evers

1
tôi đã nghĩ rằng các vật thể bất biến sẽ hữu ích cho các tính toán trung gian (trong các luồng song song)
Steven A. Lowe

11

Liệu bất biến trong miền có nghĩa là nó phải bất biến trong cơ sở dữ liệu? Ví dụ, hãy xem xét các giả định sau đây của khách hàng luôn có một địa chỉ:

customer.address = new Address('My Castle', 'Kings street');
customer_repo.save(customer);

bây giờ sql sau đây được chạy xem xét id khách hàng là 1:

INSERT INTO addresses (customer_id, name, street)
VALUES (1, 'My Castle', 'Kings street');

bây giờ thay đổi sau đây được thực hiện theo địa chỉ:

customer.address = new Address('Pauper palace', 'Outlands');
customer_repo.save(customer);

và lớp kiên trì, rất thông minh chạy sql sau:

UPDATE addresses SET name='Pauper palance', street='Outlands'
WHERE customer_id = 1;

Bằng cách này, bạn sẽ tránh được chi phí của một câu lệnh XÓA VÀ XÁC NHẬN riêng biệt. Ngoài ra, tôi nghĩ rằng một số RDBMS có L REPI thay thế hoặc một cái gì đó. MySql đã thay thế .


+1 Tôi đồng ý với bạn về nguyên tắc chung: Tôi không hiểu tại sao các đối tượng miền bất biến nhất thiết phải có nghĩa là các hàng DB bất biến.
Andres F.

? Trong trường hợp trên, nếu chúng ta không bao giờ cần phải thay đổi các thuộc tính thành phố của lớp địa chỉ cho khách hàng nhất định như thế nào, chúng tôi sẽ xử lý nó, Hơn nữa giả định khách hàng có thể có nhiều địa chỉ để nó aa một đến nhiều tàu mối quan hệ giữa khách hàng và địa chỉ
Sudarshan

1
@Sudarshan đây chỉ là một cách để tạo ra một 'đối tượng giá trị bất biến', không thực sự bất biến trong cơ sở dữ liệu. Vì lý do hiệu suất. Mỗi tình huống cần phải được xử lý cụ thể. Bây giờ tôi thích Tìm nguồn cung cấp sự kiện cho Tên miền của mình, nhưng tôi nghiện nó.
andho

@Sudarshan để trả lời câu hỏi của bạn một cách cụ thể, Bạn chỉ cần chạy một truy vấn cập nhật để cập nhật hàng thành giá trị mới. Nếu nó là một-nhiều, thì các địa chỉ sẽ có một số loại định danh trong Root Tổng hợp khách hàng sẽ được sử dụng để nhận dạng duy nhất nó trong DB. Sau đó, mã định danh này và customer_id sẽ được sử dụng để cập nhật hàng đó trong bảng 'địa chỉ'.
andho

@andho "đây chỉ là một cách để tạo ra một 'đối tượng giá trị bất biến', không thực sự bất biến trong cơ sở dữ liệu." điều này thực sự làm cho ngày của tôi cảm ơn
Sudarshan

6

Trong DDD, các đối tượng bất biến tương đương với các đối tượng giá trị. Những đối tượng này không phải là thực thể, họ không có danh tính. Do đó, tôi luôn duy trì các đối tượng giá trị dưới dạng colums của thực thể mà chúng được chứa trong (với N / Hibernate bạn có thể sử dụng Thành phần cho điều đó). Họ không có một cái bàn của riêng mình.


4

Nó phụ thuộc vào cách đối tượng bất biến được ánh xạ trong cơ sở dữ liệu. Nếu nó chỉ là một thành phần như DateTime (từ thư viện Joda Time) thì việc thay đổi giá trị sẽ dẫn đến cập nhật thay vì chèn. Tuy nhiên, nếu bất biến phức tạp hơn đòi hỏi một hàng trong một bảng thì bạn đã gặp vấn đề phình to.

Tôi cho rằng, mặc dù đó là một đối số yếu, bạn có thể thực hiện một lộ trình kiểm toán theo cách này. Mọi thay đổi đối với immmutable đều có thể được theo dõi thông qua các phần chèn. Có nhiều cách tốt hơn để làm điều này mặc dù.

Tất cả trong tất cả đều có các đối tượng miền bất biến (thay vì chỉ đơn thuần là các thành phần của chúng) có vẻ hơi không phù hợp với sự bền bỉ.


Không có gì. Các thành phần rất hữu ích vì chúng cho phép các đối tượng miền được cấu tạo khác với cùng một dữ liệu cơ bản. Các vấn đề đi kèm với thực thi bất biến. Cá nhân, tôi sẽ coi các đối tượng miền là có thể thay đổi (ngoại trừ các trường khóa chính) và giữ cho nó đơn giản.
Gary Rowe

"Tất cả trong tất cả đều có các đối tượng miền bất biến (thay vì chỉ đơn thuần là các thành phần của chúng) có vẻ hơi không phù hợp với sự bền bỉ." Theo ý kiến ​​của bạn, chúng ta cần có những đối tượng giá trị nào không nên được mô hình hóa thành các thành phần (thuật ngữ Hibernate)? --- Xin lỗi tôi đã nhập sai nhận xét cuối cùng của mình và do đó đã xóa nó.
Sudarshan

Tránh các thành phần khi một thực thể duy nhất được biểu thị đầy đủ bởi một hàng và không có dữ liệu nào được chia sẻ bởi một đối tượng miền khác.
Gary Rowe

4

Điều đó phụ thuộc vào tên miền. DDD không xác định rằng mô hình lập trình là hướng đối tượng. Tuy nhiên, mô hình hướng đối tượng là một mô hình phù hợp cho ứng dụng điển hình phải được duy trì trong cơ sở dữ liệu.

DDD chỉ đơn giản nói rằng bạn nên xây dựng phần mềm của mình xung quanh một mô hình miền đại diện cho vấn đề thực tế mà phần mềm đang cố gắng giải quyết. Nếu bản chất vấn đề đó là toán học, thì việc triển khai lớp miền bằng cách sử dụng lập trình chức năng và cấu trúc dữ liệu bất biến sẽ có nhiều ý nghĩa.

Mặt khác, vấn đề là ở một ứng dụng doanh nghiệp điển hình và bạn đang sử dụng các cấu trúc đối tượng bất biến cho tất cả các đối tượng miền của mình, thì tôi sẽ cho rằng bạn không theo dõi DDD. Tôi có thể đưa ra ít nhất hai đối số:

  • Việc triển khai của bạn không đại diện cho một mô hình miền của miền vấn đề của bạn. Miền vấn đề của bạn trong trường hợp này bao gồm các thực thể có trạng thái để sửa đổi. Và đó không phải là cách bạn đã thực hiện nó.

  • Bạn không có một ngôn ngữ phổ biến. Ngôn ngữ và các khái niệm trong mô hình miền không tuân theo những gì các chuyên gia tên miền đang sử dụng.

Lưu ý: DDD không sử dụng các đối tượng bất biến khi thích hợp, chúng chỉ được gọi là các đối tượng giá trị.

Vì vậy, tôi không nói rằng bạn không thể tạo một ứng dụng cơ sở dữ liệu bằng cách sử dụng các cấu trúc dữ liệu chức năng thuần túy và tôi không nói rằng bạn không nên. Tôi chỉ không nghĩ rằng bạn có thể gọi nó là DDD, tùy thuộc vào loại ứng dụng


Peter, câu trả lời tuyệt vời. Bạn có thể xem câu hỏi của tôi ở đây stackoverflow.com/questions/13783666/ và giúp tôi tìm ra vấn đề của mình. Tôi nghĩ các đối tượng giá trị bất biến là tuyệt vời cho các phần mềm không liên quan đến doanh nghiệp. Theo tôi, hầu hết các đối tượng của ứng dụng doanh nghiệp đều có thể thay đổi. Hãy tưởng tượng có một đối tượng giá trị được lồng sâu bất biến ... ContactInfo-> PhysLocation-> Địa chỉ và bạn muốn cập nhật mã zip ... tạo ra toàn bộ biểu đồ đối tượng đối với tôi, không chỉ là một antipotype. bạn nghĩ sao?
Pepito Fernandez

3

Nếu bạn đang sử dụng ORM như Hibernate / NHibernate, bạn có thể đặt tùy chọn xếp tầng của mình để tự động xóa các đối tượng mồ côi. Nếu một người có Địa chỉ đối tượng giá trị, khi bạn thay đổi địa chỉ, địa chỉ mới sẽ được lưu và địa chỉ cũ bị xóa vì hiện tại nó đã mồ côi.


0

Các đối tượng giá trị hầu như luôn luôn bất biến trong DDD và mẫu fly trọng có thể được sử dụng để giữ sự trùng lặp của đối tượng giá trị đó trong bộ nhớ giống như .NET thực hiện với các chuỗi. Sự đánh đổi chính là bộ nhớ một bên và bên còn lại là hiệu quả sáng tạo. Với mẫu fly trọng, phải thực hiện so sánh dựa trên giá trị để xác định xem có bất kỳ đối tượng giá trị mới hoặc hoàn nguyên nào đã có trong bộ đệm bay không, nhưng mọi so sánh khác sau thời điểm đó có thể được thực hiện một cách an toàn bằng cách tham chiếu vì một trường hợp duy nhất được thi hành. Dù bằng cách sử dụng fly weight hay không, các đối tượng giá trị vẫn được tạo ra bất biến vì chúng chỉ có bản sắc nội tại và do đó thay đổi giá trị của chúng sẽ thay đổi danh tính của chúng.


-1

Có một cách khác để sử dụng các vật thể bất biến ...

Thay vì lưu trữ các giá trị 5.0, 6.0, 7.0, 8.0 và sao chép toàn bộ bản ghi mỗi lần, bạn có thể lưu trữ một cái gì đó như thế này: 5.0, +1.0, +1.0, +1.0, sau đó xây dựng một phụ thuộc chính xác để xây dựng lại chuỗi 5.0 , 6.0, 7.0, 8.0. Bằng cách này, những sửa đổi nhỏ chỉ chiếm một lượng nhỏ bộ nhớ ...

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.