Estoy tratando de encontrar una mejor manera de manejar algunas construcciones if
en crecimiento para manejar clases de diferentes tipos. Estas clases son, en última instancia, envoltorios de tipos de valores dispares (int, DateTime, etc.) con información de estado adicional. Entonces, la principal diferencia entre estas clases es el tipo de datos que contienen. Si bien implementan interfaces genéricas, también deben mantenerse en colecciones homogéneas, por lo que también implementan una interfaz no genérica. Las instancias de clase se manejan de acuerdo con el tipo de datos que representan y su propagación continúa o no continúa en función de eso.Double-dispatch y alternativas
Si bien esto no es necesariamente un problema de .NET o C#, mi código está en C#.
clases Ejemplo:
interface ITimedValue {
TimeSpan TimeStamp { get; }
}
interface ITimedValue<T> : ITimedValue {
T Value { get; }
}
class NumericValue : ITimedValue<float> {
public TimeSpan TimeStamp { get; private set; }
public float Value { get; private set; }
}
class DateTimeValue : ITimedValue<DateTime> {
public TimeSpan TimeStamp { get; private set; }
public DateTime Value { get; private set; }
}
class NumericEvaluator {
public void Evaluate(IEnumerable<ITimedValue> values) ...
}
he llegado con dos opciones:
doble Despacho
Hace poco supe del patrón del visitante y su uso del doble de despacho de manejar solo tal caso. Esto es atractivo porque permitiría que los datos no deseados no se propaguen (si solo queremos manejar un int, podemos manejarlo de manera diferente a DateTime). Además, los comportamientos de cómo se manejan los diferentes tipos se limitarán a la única clase que maneja el envío. Pero hay un poco de mantenimiento si/cuando un nuevo tipo de valor tiene que ser compatible.
Unión Clase
Una clase que contiene una propiedad para cada tipo de valor con el apoyo podría ser lo que cada una de estas clases de tienda. Cualquier operación en un valor afectaría el componente apropiado. Esto es menos complejo y menos mantenimiento que la estrategia de doble envío, pero significaría que cada pieza de datos se propagaría innecesariamente, ya que no se puede discriminar a lo largo de las líneas de "No opero con ese tipo de datos". ". Sin embargo, si/cuando los tipos nuevos necesitan soporte, solo necesitan ingresar a esta clase (más las clases adicionales que deban crearse para admitir el nuevo tipo de datos).
class UnionData {
public int NumericValue;
public DateTime DateTimeValue;
}
¿Hay mejores opciones? ¿Hay algo en cualquiera de estas dos opciones que no consideré que debería?
¿Qué podría ocurrir en el método 'Evaluate' de' NumericEvaluator' que funcionaría en un 'DateTime' * o * a' float'? –
en un móvil en este momento, así que no puedo escribir una respuesta adecuada, pero trate de buscar en Google el uso de la dinámica para despacho doble (que reduce en gran medida el estándar requerido por el patrón de visitante) o la implementación de tipos de unión en C# (recuerdo una hermosa implementación de @Juliet en algún lugar aquí en SO) –
@Chris Shain: Eso es parte del beneficio de la solución de doble despacho, no debería ser así. Para un 'DateTime', la solución de doble envío lo ignora o la solución variante lo consume como un valor 0. – redman