Trabajo en un sistema que puede representar una "estimación de envío" de dos maneras:
- Una fecha específica: el artículo está garantizado para enviarse en esa fecha
- Intervalo de un día: el artículo se enviará en días "X a Y" a partir de hoy
La información sobre el modelo es semánticamente la misma, es "la estimación de envío". Cuando obtengo la información sobre la estimación de envío del sistema, puedo decir si la estimación es de la primera forma o la segunda forma.
El modelo actual para esto es similar al siguiente:
class EstimattedShippingDateDetails
{
DateTime? EstimattedShippingDate {get; set;}
Range? EstimattedShippingDayRange {get; set;}
}
Range
es una clase simple para envolver un "principio -> fin" de enteros, algo así:
struct Range
{
int Start {get; set}
int End {get; set}
public override ToString()
{
return String.Format("{0} - {1}", Start, End);
}
}
No me gusta este enfoque porque solo se completará una de las propiedades en el modelo de estimación, y necesito probar nulo en uno de ellos y asumir que el otro tiene los datos.
Cada una de las propiedades se muestra de manera diferente para el usuario, pero en el mismo lugar en la interfaz de usuario, utilizando una MVC DisplayTemplate personalizada, donde reside la lógica de conmutación actual:
@Model EstimattedShippingDateDetails
@if (Model.EstimattedShippingDate.HasValue)
{
Html.DisplayFor(m => Model.EstimattedShippingDate)
}
else
{
Html.DisplayFor(m => Model.EstimattedShippingDayRange)
}
¿Cómo podría modelar esto para hacerlo más representativo del requisito real y al mismo tiempo mantener la lógica de visualización simple en una aplicación MVC?
Pensé en usar una interfaz y dos implementaciones, una para cada "tipo" de estimación, pero parece que no puedo entender una interfaz común para ambas. Si creo una interfaz sin ningún miembro, entonces no puedo acceder a los datos de manera unificada y es un mal diseño en mi humilde opinión. También quería mantener el modelo de vista lo más simple posible. Sin embargo, obtendría un código "correcto por construcción" con este enfoque, ya que ya no sería necesario anular: cada implementación tendría una propiedad no anulable, ya sea a DateTime
o a Range
.
También consideré usar solo uno Range
y cuando ocurre la situación n. ° 1, solo use el mismo DateTime
para ambos Start
y End
, pero esto agregaría complicaciones sobre cómo emitir los valores a la interfaz de usuario, ya que luego tendría que detectar si es estático o intervalo por comparar los valores y formatear correctamente el rango para que se muestre como una sola fecha o un intervalo formateado.
Parece que lo que necesito es un concepto similar a las uniones de Typecript: básicamente una propiedad que puede ser de dos tipos. No existe tal cosa de forma nativa en C #, por supuesto (solo dynamic
estaría cerca de eso).