Tôi làm việc trong một hệ thống có thể đại diện cho "ước tính vận chuyển" theo hai cách:
- Một ngày cụ thể: Các mặt hàng được đảm bảo để vận chuyển vào ngày đó
- Một khoảng thời gian trong ngày: Các mặt hàng sẽ được vận chuyển "X đến Y" ngày kể từ hôm nay
Thông tin trên mô hình giống nhau về mặt ngữ nghĩa, đó là "ước tính vận chuyển". Khi tôi nhận được thông tin về ước tính vận chuyển từ hệ thống, tôi có thể biết liệu ước tính đó là dạng thứ nhất hay dạng thứ hai.
Mô hình hiện tại cho điều này tương tự như sau:
class EstimattedShippingDateDetails
{
DateTime? EstimattedShippingDate {get; set;}
Range? EstimattedShippingDayRange {get; set;}
}
Range
là một lớp đơn giản để bao bọc "bắt đầu -> kết thúc" các số nguyên, hơi giống như thế này:
struct Range
{
int Start {get; set}
int End {get; set}
public override ToString()
{
return String.Format("{0} - {1}", Start, End);
}
}
Tôi không thích cách tiếp cận này vì chỉ một trong số các thuộc tính trên mô hình ước tính sẽ được đưa vào và tôi cần kiểm tra null cho một trong số chúng và giả sử rằng thuộc tính kia có dữ liệu.
Mỗi thuộc tính được hiển thị khác nhau cho người dùng nhưng ở cùng một vị trí trên giao diện người dùng, sử dụng MVC DisplayTemplate tùy chỉnh, nơi logic chuyển đổi hiện tại nằm trong:
@Model EstimattedShippingDateDetails
@if (Model.EstimattedShippingDate.HasValue)
{
Html.DisplayFor(m => Model.EstimattedShippingDate)
}
else
{
Html.DisplayFor(m => Model.EstimattedShippingDayRange)
}
Làm thế nào tôi có thể mô hình hóa điều này để làm cho nó đại diện hơn cho yêu cầu thực tế trong khi vẫn giữ logic hiển thị đơn giản trong một ứng dụng MVC?
Tôi đã nghĩ về việc sử dụng một giao diện và hai triển khai, một cho mỗi "loại" ước tính, nhưng dường như tôi không thể quấn đầu quanh một giao diện chung cho cả hai. Nếu tôi tạo một giao diện mà không có bất kỳ thành viên nào, thì tôi không thể truy cập dữ liệu theo cách thống nhất và đó là một thiết kế xấu IMHO. Tôi cũng muốn giữ cho viewmodel đơn giản nhất có thể. Tuy nhiên, tôi sẽ nhận được mã "chính xác bằng cách xây dựng" với cách tiếp cận này, vì sẽ không cần phải có bất kỳ giá trị null nào nữa: mỗi triển khai sẽ có một thuộc tính không thể rỗng, a DateTime
hoặc a Range
.
Tôi cũng đã cân nhắc chỉ sử dụng một lần duy nhất Range
và khi tình huống # 1 xảy ra, chỉ sử dụng tương tự DateTime
cho cả hai Start
và End
, nhưng điều này sẽ làm tăng thêm sự phức tạp về cách phát ra các giá trị cho UI khi tôi sẽ phải phát hiện xem đó là tĩnh hay khoảng so sánh các giá trị và định dạng đúng phạm vi sẽ được hiển thị dưới dạng một ngày hoặc một khoảng thời gian được định dạng.
Dường như những gì tôi cần là một khái niệm tương tự như các hiệp hội của Typecript: về cơ bản là một thuộc tính có thể thuộc bất kỳ loại nào. Tất nhiên không có một thứ như vậy tồn tại trong C # (chỉ dynamic
có thể gần với điều đó).