TL; DR - Estou tentando projetar uma estrutura de dados ideal para definir unidades dentro de uma unidade de medida.
A Unit of measure
é essencialmente uma value
(ou quantidade) associada a a unit
. As unidades SI possuem sete bases ou dimensões. A saber: comprimento, massa, tempo, corrente elétrica, temperatura, quantidade de substância (moles) e intensidade luminosa.
Isso seria bastante direto, mas há várias unidades derivadas e taxas que usamos com frequência. Um exemplo de unidade combinada seria o Newton: kg * m / s^2
e uma taxa de exemplo seria tons / hr
.
Temos um aplicativo que depende muito de unidades implícitas. Incorporaremos as unidades no nome da variável ou coluna. Mas isso cria problemas quando precisamos especificar uma unidade de medida com unidades diferentes. Sim, podemos converter os valores na entrada e na exibição, mas isso gera muitos códigos gerais que gostaríamos de encapsular dentro de sua própria classe.
Existem várias soluções no codeplex e em outros ambientes colaborativos. O licenciamento para os projetos é agradável, mas o próprio projeto geralmente acaba sendo muito leve ou muito pesado. Estamos perseguindo nosso próprio unicórnio de "exatamente certo".
Idealmente, eu poderia definir uma nova unidade de medida usando algo como isto:
UOM myUom1 = nova UOM (10 volts);
UOM myUom2 = nova UOM (43,2, Newtons);
Obviamente, usamos uma mistura de unidades imperiais e SI com base nas necessidades de nossos clientes.
Também precisamos manter essa estrutura de unidades sincronizada com uma tabela futura do banco de dados para que também possamos fornecer o mesmo grau de consistência em nossos dados.
Qual é a melhor maneira de definir as unidades, unidades derivadas e taxas que precisamos usar para criar nossa classe de unidade de medida? Eu pude ver usando uma ou mais enumerações, mas isso pode ser frustrante para outros desenvolvedores. Uma única enumeração seria enorme com mais de 200 entradas, enquanto várias enumerações poderiam ser confusas com base nas unidades SI vs Imperial e em detalhes adicionais com base na categorização da própria unidade.
Exemplos enum mostrando algumas das minhas preocupações:
myUnits.Volt
myUnits.Newton
myUnits.meterSIUnit.meter
ImpUnit.foot DrvdUnit.Newton
DrvdUnitSI.Newton
DrvdUnitImp.FtLbs
Nosso conjunto de unidades em uso é muito bem definido e é um espaço finito. Precisamos da capacidade de expandir e adicionar novas unidades ou taxas derivadas quando houver demanda dos clientes por elas. O projeto está em C #, embora eu ache que os aspectos mais amplos do design sejam aplicáveis a vários idiomas.
Uma das bibliotecas que eu analisei permite a entrada de unidades de forma livre via string. A classe UOM deles analisou a sequência e colocou as coisas de acordo. O desafio dessa abordagem é que ela força o desenvolvedor a pensar e lembrar quais são os formatos corretos de string. E corro o risco de um erro / exceção de tempo de execução, se não adicionarmos verificações adicionais no código para validar as seqüências que estão sendo passadas no construtor.
Outra biblioteca criou essencialmente muitas classes com as quais o desenvolvedor teria que trabalhar. Juntamente com uma UOM equivalente forneceu um DerivedUnit
e RateUnit
e assim por diante. Essencialmente, o código era excessivamente complexo para os problemas que estamos resolvendo. Essa biblioteca permitiria essencialmente qualquer: qualquer combinação (o que é legítimo no mundo das unidades), mas estamos felizes em analisar nosso problema (simplificar nosso código), não permitindo todas as combinações possíveis.
Outras bibliotecas eram ridiculamente simples e nem sequer consideravam a sobrecarga do operador, por exemplo.
Além disso, não estou tão preocupado com tentativas de conversões incorretas (por exemplo: volts em metros). Os desenvolvedores são os únicos que acessarão neste nível neste momento e não precisamos necessariamente proteger contra esses tipos de erros.