Sto cercando di trovare un modo migliore per gestire alcuni costrutti if
in crescita per gestire classi di tipi diversi. Queste classi sono, in definitiva, wrapper attorno a diversi tipi di valore (int, DateTime, ecc.) Con alcune informazioni aggiuntive sullo stato. Quindi la differenza principale tra queste classi è il tipo di dati che contengono. Mentre implementano interfacce generiche, devono anche essere conservate in raccolte omogenee, quindi implementano anche un'interfaccia non generica. Le istanze di classe vengono gestite in base al tipo di dati che rappresentano e la loro propagazione continua o non continua in base a ciò.Doppia-dispatch e alternative
Sebbene questo non sia necessariamente un problema .NET o C#, il mio codice è in C#.
classi Esempio:
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) ...
}
ho fornito con due opzioni:
doppio spedizione
recente ho appreso del modello visitatore e il suo uso della doppia spedizione per gestire solo un caso del genere. Questo fa appello perché permette ai dati indesiderati di non propagarsi (se vogliamo solo gestire un int, possiamo gestirlo in modo diverso rispetto a un DateTime). Inoltre, i comportamenti di come vengono gestiti i diversi tipi sarebbero limitati alla singola classe che sta gestendo la spedizione. Ma c'è un bel po 'di manutenzione se/quando un nuovo tipo di valore deve essere supportato.
dell'Unione Classe
Una classe che contiene una proprietà per ogni tipo di valore supportato potrebbe essere quello che ciascuna di queste classi negozio. Qualsiasi operazione su un valore influenzerebbe il componente appropriato. Questo è meno complesso e meno di manutenzione rispetto alla strategia di doppia spedizione, ma significherebbe che tutti i dati verrebbero propagandati inutilmente in quanto non è più possibile discriminare sulla falsariga di "Non operare su quel tipo di dati ". Tuttavia, se/quando i nuovi tipi devono essere supportati, devono solo entrare in questa classe (più qualsiasi altra classe aggiuntiva che deve essere creata per supportare il nuovo tipo di dati).
class UnionData {
public int NumericValue;
public DateTime DateTimeValue;
}
Ci sono opzioni migliori? C'è qualcosa in queste due opzioni che non ho ritenuto che dovrei?
Cosa potrebbe accadere nel metodo 'Evaluate' di' NumericEvaluator' che opererebbe su un 'DateTime' * o * a' float'? –
su un cellulare in questo momento, quindi non posso scrivere una risposta adeguata, ma provare a cercare su google l'uso della dinamica per la doppia spedizione (che riduce notevolmente il boilerplate richiesto dal pattern del visitatore) o l'implementazione dei tipi di unione in C# (Ricordo una bella implementazione di @Juliet da qualche parte qui su SO) –
@Chris Shain: Questo è parte del vantaggio della soluzione a doppia spedizione - non dovrebbe. Per un 'DateTime', la soluzione a doppia spedizione la ignora o la soluzione variante la consuma come valore 0. – redman