2010-09-13 11 views
6

Tôi đang làm việc trên một ứng dụng ASP.NET MVC, thiết kế các mô hình miền, sử dụng (thử nghiệm) tính năng EF Code First mới.Whats thiết kế/thực hành tốt hơn: Thuộc tính dễ vỡ hoặc thuộc tính 1 giá trị và 1 bool "có" thuộc tính?

Tôi có một thực thể Hoạt động có thể có hoặc không có Hạn chót, cách tốt nhất để tiếp cận nó là gì?

1 bất động sản:

public DateTime? Deadline {get; set;} 
and check vs null before using 

hoặc

2 thuộc tính:

public DateTime Deadline {get; set;} 
public bool HasDeadline {get; set;} 

Lúc đầu, tôi nghĩ đến các tùy chọn đầu tiên, nhưng sau đó tôi bắt đầu nghĩ rằng có lẽ tùy chọn thứ hai sẽ là tốt hơn về DB ...

Có thực tiễn nào tốt nhất liên quan đến điều này không ?

Trả lời

10

Tôi muốn sử dụng tùy chọn đầu tiên. Xét cho cùng, chính xác là chính xác dạng đóng gói thứ hai.

Việc đóng gói cho thấy rõ ràng rằng bạn chỉ có một giá trị hợp lý (hoặc thiếu). Ở dạng thứ hai, bạn có thể xem các thuộc tính như thể chúng hoàn toàn độc lập, chúng không hợp lý.

Về cơ sở dữ liệu, tôi cho rằng biểu mẫu đầu tiên cũng dễ dàng như vậy ... presuambly bạn sẽ có trường DATETIME rỗng trong cơ sở dữ liệu, phải không? Nó nên ánh xạ trực tiếp.

+0

Tôi muốn đi với các tùy chọn đầu tiên nếu 'HasDeadline' chỉ ảnh hưởng đến 'Deadline' cột. Nếu nó ảnh hưởng đến nhiều trường hoặc hành vi, thì một cột riêng biệt có thể thích hợp (có cột 'OverduePenalty' chỉ có ý nghĩa nếu có hạn chót không?). Hãy suy nghĩ xem liệu bạn có nhiều truy vấn dọc theo các dòng 'KHÔNG CÓ THƯỜNG NIÊN' ('Hạn chót') ', bởi vì 'WHERE' HasDeadline'' cảm thấy sạch hơn nhiều. –

+0

Vì hes làm mã đầu tiên trên một mô hình miền, ai quan tâm đến SQL trông như thế nào? Làm cho miền đẹp, và có thể sử dụng, sau đó lo lắng về phía cơ sở dữ liệu của nó. –

+0

Sự khác biệt cũng xuất hiện trong LINQ. –

1

Tôi sẽ sử dụng tùy chọn đầu tiên. Về lâu dài, tùy chọn thứ hai có thể sẽ gây ra một số vấn đề về bảo trì vì bạn phải nhớ kiểm tra và sử dụng cả hai thuộc tính.

Cũng có một tùy chọn là sử dụng một thuộc tính nhưng thay vì làm cho nó không có giá trị, bạn có thể trả lại Null object (còn được gọi là Special Case).

1

Cơ sở dữ liệu được sử dụng để lưu trữ giá trị NULL - lưu trữ giá trị Min trong databsae và sau đó có cờ để cho biết liệu bạn có nên tin tưởng giá trị đó làm cho truy vấn phức tạp hay không.

Tôi thích các loại có thể vô hiệu do phản ánh ý định của tên miền - không có ngày, không phải 'không có ngày, vì vậy giả vờ đầu tiên của tháng 1 năm 1970 nghĩa là không có ngày'.

Ngoài ra còn có chi phí duy trì giá trị HasDealine - bạn cần phải đặt giá trị đó mỗi khi thuộc tính tương ứng được cập nhật. Ngoài ra làm thế nào để bạn xóa nó? Nếu bạn đặt Hạn chót cho một ngày, nó sẽ đặt HasDeadline thành true. Làm cách nào để 'bỏ đặt' nó? Bạn có đặt HasDeadline thành false hay không, nhưng để nguyên trường Hạn chót nguyên vẹn với giá trị trước đó?

Toàn bộ icky.

+0

Tất cả những vấn đề này tồn tại với 'Nullable ' là tốt, và giải pháp "ném một ngoại lệ từ giá trị getter nếu HasValue là sai" không phải là tất cả những gì tuyệt vời, IMHO. –

+0

Ý bạn là chúng tồn tại như thế nào? Vì tôi có thể gán 'null' cho một' Nullable 'loại tôi có một cách thực sự đơn giản để 'xóa' giá trị. Vì tôi không thể gán 'null' cho' DateTime' làm cách nào để chỉ ra rằng thực thể không còn có một hạn chót? Và tất nhiên, không bao giờ ném một ngoại lệ cho cái gì đó không phải là ngoại lệ. Đó là lý do tại sao HasValue ở đó, vì vậy bạn có thể đánh giá nó trước khi làm điều gì đó. Quan điểm của tôi là HasValue trên Nullable là tất cả có dây cho bạn. Dễ dàng, tốt để đi, và không yêu cầu hệ thống ống nước lặp đi lặp lại mỗi bạn muốn sử dụng nó. –

+1

Bạn thực sự không thể gán 'null' cho' Nullable ', trình biên dịch đang nói dối bạn. Bạn đang thực sự gán 'mặc định (Nullable )' (tức là mặc định được xây dựng 'Nullable '), đó là một kiểu giá trị, có nghĩa là số nguyên nhị phân - 'HasValue' trở thành false và' Value' trở thành 'mặc định (T) 'bất kể giá trị tất cả 0 của' T' có nghĩa là gì. –

1

Bạn nên sử dụng giá trị rỗng, vì nó thực hiện chính xác những gì bạn muốn. Sử dụng hai thuộc tính riêng biệt có nghĩa là bạn mất kết nối giữa chúng và bạn cần giải thích bằng tài liệu có mối quan hệ.

Loại vô hiệu cũng phải phù hợp hơn với kiểu cơ sở dữ liệu, tuy nhiên trước tiên bạn nên thiết kế đối tượng của bạn để nó hoạt động như một đối tượng chứ không phải cách bạn lưu trữ nó trong cơ sở dữ liệu.Nếu việc sử dụng một công cụ tạo cơ sở dữ liệu khiến bạn đưa ra các quyết định tồi khi thiết kế mã, nó sẽ không hiệu quả.

3

Làm thế nào về sự kết hợp của cả hai chỉ để làm cho mã của bạn dễ đọc hơn?

public DateTime? Dealine{get; set;} 
public bool HasDeadline 
{ 
    get 
    { 
     return (Deadline != null); 
    } 
} 

Dễ đọc và thực hiện chính xác điều tương tự mà người tiêu dùng sẽ phải làm. Bên cạnh đó ...

if(HasDeadline) 
    doStuff(); 

là dễ đọc hơn

if(Dealine != null) 
    doStuff(); 

:)

+3

Điều gì về: 'if (Deadline.Hasvalue)' trái với 'if (HasDeadline)'. Bạn không cần phải so sánh với null vì 'Nullable ' có phương thức 'HasValue' được xây dựng. –