2014-05-02 19 views
7

Tôi đã tò mò về suy nghĩ của mọi người về việc giữ Id của một thực thể DAL như một thuộc tính của thực thể miền, tại thuộc tính chỉ đọc tuyệt đối.Các đối tượng Model và Domain Model Persistance

Suy nghĩ đầu tiên của tôi là điều này là ok nhưng tôi càng nghĩ về nó thì tôi càng không thích ý tưởng đó. Sau khi tất cả các mô hình miền là nghĩa vụ phải hoàn toàn không biết về cách dữ liệu được duy trì, và giữ và Id tài sản trên mỗi mô hình miền là một dấu hiệu ít hơn-tinh tế. Lớp kiên trì có thể là thứ không yêu cầu khóa chính hoặc một thuộc tính khác được hiển thị trong mô hình miền có thể là một ứng cử viên thích hợp để nhận dạng, một mô hình không. có lẽ. Nhưng sau đó tôi nghĩ, đối với các mô hình miền không có phương tiện đáng tin cậy để xác định duy nhất một mục trong lớp kiên trì cơ sở dữ liệu, làm cách nào để xác định các mục khi cập nhật hoặc xóa?

Từ điển dựa trên các khóa tham chiếu yếu có thể thực hiện thủ thuật; WeakDictionary<DomainEntity, PrimaryKeyType>. Từ điển này sẽ là một phần của việc triển khai kho lưu trữ, bất cứ khi nào máy khách của kho lưu trữ Tìm nạp một bộ sưu tập của DomainEntity một tham chiếu yếu đến thực thể và Id lưu giữ lâu bền của nó được lưu trữ trong từ điển nội bộ này. tổ chức vào kho để cập nhật lớp kiên trì, sau đây có thể được thực hiện để lấy lại id

PrimaryKeyType id = default(PrimaryKeyType); 
if (!weakDictionary.TryGetValue(someDomainEntity, out id)) 
    // id not found, throw exception? custom or otherwise.. 

// id found, continue happily mapping domain model back to data model. 

những lợi ích của phương pháp này như tôi nhìn thấy nó, là đơn vị miền không cần duy trì id cụ thể lớp kiên trì của nó và kho lưu trữ buộc bạn phải có một thực thể miền hợp pháp thu được hoặc bằng một số cuộc gọi đến phương thức Fetch... hoặc phương pháp Add/CreateNew, e lse bạn nên cố gắng cập nhật/xóa các thực thể nó sẽ ném một ngoại lệ.

Tôi biết rằng điều này có lẽ quá kỹ thuật và tôi chỉ nên khóa xuống và thực dụng, tôi chỉ tò mò về những gì người khác nghĩ về điều này.


Tôi không muốn bắt đầu một chuỗi khác chỉ cho câu hỏi nhỏ này vì nó có phần liên quan. Nhưng vì gần đây tôi đã bắt đầu xem xét DDD (mặc dù trong trường hợp này cơ sở dữ liệu của tôi xuất hiện trước) Tôi tự hỏi liệu tôi có thể xác nhận rằng tôi có tư duy đúng đắn cho Thực thể miền hay không, đây là một ví dụ được cắt giảm về thực thể miền Nhân viên của tôi.

public class Employee : DomainEntity 
{ 
    public string FirstName { get; } 
    public string LastName { get; } 
    public UserGroup Group { get; } 
    // etc.. 


    // only construct valid employees 
    public Employee(string firstName, string lastName, SecureString password, UserGroup group); 

    // validate, update. (not sure about this one.. pulled it 
    // from an open source project, I think that names should be able to be set individually). 
    AssignName(string firstName, string lastName); 

    // validate, update. 
    ResetPassword(SecureString oldPassword, SecureString newPassword); 

    // etc.. 
} 

Cảm ơn bạn!

+0

Bạn nên cắt giảm một chút về rác và hỏi một câu hỏi _real_ (không phải là một cuộc thảo luận) nếu bạn muốn câu hỏi này được trả lời (và vẫn mở) – Shoe

+4

@ShoeMay: Tôi không đồng ý. Đây là một câu hỏi có liên quan và có cấu trúc tốt. Những khái niệm thực hiện DDD thường bị gánh nặng nặng nề bởi các câu hỏi thiết kế như thế này. – davenewza

Trả lời

4

Đề xuất sử dụng tài liệu tham khảo yếu của bạn có một lỗ hổng lớn.

Như bạn có thể biết, thực thể miền có đặc điểm quan trọng ở chỗ chúng phải có nhận dạng. Điều này rất quan trọng vì lý do so sánh. Nếu hai thực thể có bản sắc đó, không phụ thuộc vào giá trị của tài sản của họ, sau đó chúng được coi là bình đẳng:

Entity1 == Entity2 ⇔ Entity1.Identity == Entity2.Identity 

Một "mẫu thiết kế" điển hình sẽ được kế thừa toàn bộ các đối tượng từ một lớp trừu tượng DomainEntity<T>, mà đè so sánh các đối tượng này và so sánh với danh tính.

Bây giờ, hãy xem xét cách tiếp cận của bạn khi sử dụng tài liệu tham khảo yếu. Hãy lấy ví dụ:

Bạn tìm nạp Entity1, giả sử người dùng "Reegan Layzell", từ kho lưu trữ.Sau đó, bạn lấy chính xác thực thể "Reegan Layzell" từ kho lưu trữ một lần nữa dưới dạng Entity2. Bây giờ bạn có cùng một thực thể trong miền của bạn trong hai đối tượng. Nhưng họ có sự tham chiếu khác biệt (tất nhiên).

Khi so sánh, những tổ chức này sẽ không được coi là bình đẳng trong phạm vi của mình.

Tôi khâm phục bạn sợ hãi giới thiệu mối quan tâm cơ sở dữ liệu vào mô hình tên miền của bạn, nhưng tuyên truyền ID cơ sở dữ liệu vào các tổ chức của bạn hầu như không sẽ ảnh hưởng đến chất lượng của mô hình của bạn và nó sẽ giúp bạn tiết kiệm rất nhiều rắc rối. Như bạn đã nói, chúng ta cần phải thực dụng.

Liên quan đến Employee ví dụ của bạn: Liệu AssignName thực sự có ý nghĩa? Trong thực tế, tên của nhân viên có thực sự thay đổi sau khi sáng tạo không? Ngoài ra, có vẻ như bạn có ý tưởng đúng. Tôi thực sự khuyên bạn nên xem điều này: Crafting Wicked Domain Models bởi Jimmy Bogard.

+0

Thực ra tôi đã nhận thức được vấn đề này và giải quyết nó bằng cách thực hiện một loạt các lớp riêng trong triển khai 'WeakDictionary' của tôi. Một trong số đó so sánh giữa các tham chiếu yếu bằng cách ghi đè phương thức Equals/GetHashCode thông qua 'Identity' của thực thể tham chiếu yếu. Những rắc rối tôi có với nó bây giờ là tự động loại bỏ các thực thể từ điển khi tham chiếu bị mất. Không có móc cho tôi làm một cái gì đó như thế này .. ít nhất là dễ dàng. Nó vẫn là một công việc đang tiến nhưng ở đây, hãy xem http://pastebin.com/Vt73HJzk – rtlayzell

+0

Tôi đã thử nghiệm các kịch bản mà bạn đề cập và tất cả mọi thứ đã làm việc tốt, lớp chính nó là một WIP và tôi sử dụng một bộ đếm thời gian để làm tự động dọn dẹp (giải pháp Adhoc), liên kết tuyệt vời bằng cách này, tôi đã nhìn thấy nó trước nhưng không nên có nhiều video như vậy, bao gồm DDD – rtlayzell

+0

Ngoài ra tôi đã đi đến nhận thức rằng những nhân kỹ thuật ID là cần thiết để phá vỡ uẩn lớn chỉ cần tham khảo một thực thể cụ thể chứ không phải chịu trách nhiệm về nó. Ví dụ trong một trong những dự án của tôi, tôi có một 'gốc tổng hợp Appointment' đòi hỏi một tham chiếu đến một' Client', 'Employee', và một 'Service' từng là Uẩn riêng của họ, thay vì tải và sự bền bỉ chúng thông qua việc bổ nhiệm nó có ý nghĩa đơn giản là lưu trữ một tham chiếu đến chúng thông qua ID của họ vì đó là điều duy nhất theo yêu cầu của miền – rtlayzell

Các vấn đề liên quan