TL; DR - Sto cercando di progettare una struttura dati ottimale per definire le unità all'interno di un'unità di misura.
A Unit of measure
è essenzialmente una value
(o quantità) associata a unit
. Le unità SI hanno sette basi o dimensioni. Vale a dire: lunghezza, massa, tempo, corrente elettrica, temperatura, quantità di sostanza (moli) e intensità luminosa.
Questo sarebbe abbastanza semplice, ma ci sono un certo numero di unità derivate e tassi che usiamo frequentemente. Un esempio di unità combinata sarebbe il Newton: kg * m / s^2
e un esempio di tasso sarebbe tons / hr
.
Abbiamo un'applicazione che si basa fortemente su unità implicite. Incorporeremo le unità all'interno del nome della variabile o della colonna. Ma ciò crea problemi quando è necessario specificare un'unità di misura con unità diverse. Sì, possiamo convertire i valori in input e display ma questo genera un sacco di codice ambientale che vorremmo incapsulare all'interno della sua stessa classe.
Esistono numerose soluzioni su codeplex e altri ambienti collaborativi. Le licenze per i progetti sono gradevoli ma il progetto stesso di solito finisce per essere troppo leggero o troppo pesante. Stiamo inseguendo il nostro unicorno di "giusto".
Idealmente, potrei definire una nuova unità di misura usando qualcosa del genere:
UOM myUom1 = nuovo UOM (10, volt);
UOM myUom2 = new UOM (43.2, Newton);
Naturalmente, usiamo un mix di unità imperiali e SI in base alle esigenze dei nostri clienti.
Dobbiamo anche mantenere questa struttura di unità sincronizzata con una futura tabella del database in modo da poter fornire lo stesso grado di coerenza anche nei nostri dati.
Qual è il modo migliore per definire le unità, le unità derivate e le tariffe che dobbiamo usare per creare la nostra classe di unità di misura? Ho potuto vedere usando uno o più enum, ma questo potrebbe essere frustrante per altri sviluppatori. Un singolo enum sarebbe enorme con oltre 200 voci mentre più enumerazioni potrebbero creare confusione in base alle unità SI vs Imperial e una suddivisione aggiuntiva basata sulla categorizzazione dell'unità stessa.
Esempi di Enum che mostrano alcune delle mie preoccupazioni:
myUnits.Volt
myUnits.Newton
myUnits.meterSIUnit.meter
ImpUnit.foot DrvdUnit.Newton
DrvdUnitSI.Newton
DrvdUnitImp.FtLbs
Il nostro set di unità in uso è abbastanza ben definito ed è uno spazio finito. Abbiamo bisogno della capacità di espandere e aggiungere nuove unità o tariffe derivate quando abbiamo la domanda dei clienti per loro. Il progetto è in C # anche se penso che gli aspetti più ampi del design siano applicabili a più lingue.
Una delle librerie che ho esaminato consente l'immissione in formato libero di unità tramite stringa. La loro classe UOM ha quindi analizzato la stringa e inserito le cose di conseguenza. La sfida con questo approccio è che costringe lo sviluppatore a pensare e ricordare quali sono i formati di stringa corretti. E corro il rischio di un errore / eccezione di runtime se non aggiungiamo ulteriori controlli all'interno del codice per convalidare le stringhe che vengono passate nel costruttore.
Un'altra libreria ha essenzialmente creato troppe classi con cui lo sviluppatore avrebbe dovuto lavorare. Insieme con un equivalente UM ha fornito un DerivedUnit
ed RateUnit
e così via. In sostanza, il codice era eccessivamente complesso per i problemi che stiamo risolvendo. Quella libreria essenzialmente consentirebbe qualsiasi: qualsiasi combinazione (che è legittima nel mondo delle unità) ma siamo felici di chiarire il nostro problema (semplificare il nostro codice) non permettendo ogni possibile combinazione.
Altre librerie erano ridicolmente semplici e per esempio non avevano nemmeno considerato il sovraccarico dell'operatore.
Inoltre, non sono così preoccupato per i tentativi di conversioni errate (ad esempio: volt in metri). Gli sviluppatori sono gli unici che accederanno a questo livello a questo punto e non abbiamo necessariamente bisogno di proteggerci da questi tipi di errori.