Mudanças entre as edições de "MeasureRuler"
Linha 64: | Linha 64: | ||
Para evitar esse problemas as unidades de medidas devem '''sempre ter nomes diferentes mesmo que em dimensões distintas'''. Embora não conheça nenhuma unidade de medida que tenha o mesmo o nome e represente coisas diferentes, é bom que o DEV tenha ciência dessa situação. | Para evitar esse problemas as unidades de medidas devem '''sempre ter nomes diferentes mesmo que em dimensões distintas'''. Embora não conheça nenhuma unidade de medida que tenha o mesmo o nome e represente coisas diferentes, é bom que o DEV tenha ciência dessa situação. | ||
}} | }} | ||
= Utilização da Régua = | |||
Para realizar a conversão das unidades de medidas devemos focar nos métodos '''.convertTo(...)''' da classe '''MeasureRuler'''. Há métodos simples utilizados para conversão dentro da mesma dimensão (sem utilização de equivalências) até métodos completos com a entrada de equivalências e definição da precisão de casas decimais. | |||
== Exemplos de Utilização == | |||
Veja alguns exemplos de utilização da MeasureRuler: | |||
{{java|Conversão de Unidade de Medida dentro da Mesma Dimensão|<syntaxhighlight lang="java"> | |||
// Converte 1000ml em Litros, retornará um BigDecimal com o valor de 1.000 | |||
MeasureRuler.convertTo(new BigDecimal("1000"), VolumeUnit.MILLILITER, VolumeUnit.LITER); | |||
// Converte 1000ml em Litros, mas dessa vez retornará com a precisão de 6 casas decimais. | |||
MeasureRuler.convertTo(new BigDecimal("1000"), VolumeUnit.MILLILITER, VolumeUnit.LITER, 6); | |||
// Converte 1000g em Kilogramas, com uma precisão de 6 casas decimais, retornará o valor 1.000000 | |||
MeasureRuler.convertTo(new BigDecimal("1000"), WeightUnit.GRAM, WeightUnit.KILOGRAM, 6); | |||
</syntaxhighlight>}} | |||
Para converter entre diferentes dimensões (grandezas de medidas diferentes), vamos primeiro estabelecer uma regra de equivalência entre as grandezas, podendo ser feita com qualquer unidade de medida da grandeza. | |||
Vejamos um exemplo, imagine um sistema de marcenaria que precise cadastrar uma chapa de madeira utilizada para móveis. No estoque e durante o processo de compra, referenciamos o item por unidades, pois fica mais fácil de fazer o pedido e comparar preços. Mas no momento de calcular o frete, precisamos saber qual o peso de cada chapa, ou qual o peso final do móvel produzido, de acordo com a "quantidade de chapa" (medida em metros quadrados (área)) que foi recortado e utilizado. Para ter todas essas informações precisamos estabelecer a relação entre as grandezas '''Unidades''', '''Massa (Peso)''' e '''Área'''. | |||
Imagine que após verificar o produto, descobrimos que a chama tem medida de 2m x 1,8m (=3,6m²), e que ela pesa 76Kg. Assim, montamos nossos dados de equivalência: | |||
{{java|Criando Regras de Equivalência|<syntaxhighlight lang="java"> | |||
// Regras de Equivalência | |||
MeasureRulerEquivalence eqVO = new MeasureRulerEquivalence(); | |||
eqVO.getMeasureUnitHash().put(UnitUnit.UNIT, new BigDecimal("1")); // Definimos que cada 1 Unidade... | |||
eqVO.getMeasureUnitHash().put(WeightUnit.KILOGRAM, new BigDecimal("76")); // equivale a 76Kg... | |||
eqVO.getMeasureUnitHash().put(AreaUnit.SQUAREMETER, new BigDecimal("3.6")); // e a 3,6m² | |||
</syntaxhighlight>}} | |||
Com as regras de equivalência o '''MeasureRuler'' conseguirá converter unidades conforme a necessidade. Vamos imaginar que o marceneiro precisa saber quantas chapas vamos precisar para cobrir uma área de 40m². Assim convertemos na régua: | |||
{{java|Convertendo Entre as Dimensões|<syntaxhighlight lang="java"> | |||
// Chamamos a MeasureRuler, mas agora passando as regras de conversão | |||
BigDecimal v = MeasureRuler.convertTo(eqVO, new BigDecimal("40"), AreaUnit.SQUAREMETER, UnitUnit.UNIT, 6); | |||
// o Valor de v será equivalente a 11.111111, com 6 casas decimais de precisão, conforme solicitado | |||
</syntaxhighlight>}} | |||
= Unidades de Medidas Personalizadas = | = Unidades de Medidas Personalizadas = |
Edição das 22h23min de 26 de julho de 2023
O MeasureRuler é, pela própria tradução, uma régua de medidas. Essa régua de medidas tem a intenção de oferecer aos sistemas a facilidade para converter unidades de medidas da mesma dimensão, ou até mesmo entre dimensões diferentes quando estabelecida a regra de conversão.
Definições:
- Dimensão - tipo de medida utiliza, como "Comprimento", "Área", "Volume", "Massa (Peso)", etc. Embora estas hoje sejam as dimensões que o BIS suporta, nada impede de se criar dimensões menos usuais como "Energia", "Luminosidade", "Torque", etc..
- Unidade de Medida - Unidade de medida utilizada para medir a Dimensão desejada. Por exemplo, comprimento pode ser medido em "Metros", "Centimetros", "Pés", "Polegadas", etc. "Massa" pode ser medida em "Arrobas", "Kilos", "Pounds", etc.
A classe MeasureRuler apresenta diversos métodos para conversão de forma. Para mais informações sobre eles consulte o JavaDoc da classe.
MeasureUnit
O MeasureRuler suporta várias dimensões de medidas. Cada dimensão pode conter várias unidades de medidas. A dimensão é definida pela enumeration MeasureDimension. Já as unidades de cada unidade de medida são definidas pela sua própria enumeration que estendem a interface MeasureUnit. Por exemplo:
- Volume - VolumeUnit
- Comprimento - LengthUnit
- Área - AreaUnit
- Massa (peso) - WeightUnit
- Unidades - UnitUnit
Interface MeasureUnit
Cada dimensão tem suas unidades de medidas em enumerations próprias. Assim, quando precisamos representar qualquer uma das unidades de medida utilizamos essa interface. Um exemplo: ao cadastrar um produto no sistema, a "unidade básica de estoque" dele pode ser tanto Unidades, quando Metros, Kilos, Metros Quadrados, etc.. Assim, a melhor maneira de definir este atributo no VO é através desta interface.
A interface MeasureUnit apresenta métodos como getDimension(), que retorna a enumeration de MeasureDimension para indicar que Dimensão de Medida esta Unidade pertence.
Persistência da Interface MeasureUnit
MeasureUnitDAOConverter (RFWDAO)
Por tratar-se de uma enumeration, o padrão do FrameWork é que no banco seja um campo do tipo varchar(50) (O limite recomendado de enums no RFW é de 50 chars). Mas, uma vez que a MeasureUnit é uma interface, o RFWDAO não sabe como proceder para persisti-la e reconstruir o VO com os dados do banco. Para isso temos de utilizar uma RFWDAOConverter. E para simplificar, o MeasureRuler já oferece uma implementação pronta para isso a MeasureUnitDAOConverter.
![]() |
|
Para definir um atributo no VO que seja do tipo MeasureUnit devemos ter algo como:
![]() |
Exemplos de Declaração |
@BISDAOConverter(converterClass = MeasureUnitDAOConverter.class)
@BISMetaGenericField(caption = "Unidade de Medida", required = true)
private MeasureUnit measureUnit = null;
|
Sempre que o RFWDAO ler a String no banco de dados que representa a unidade de medida, o Converter conseguirá descobrir de qual enumeration devemos realizar o "valueOf(...)".
Persistindo sem o RFWDAO
Ao persistir o RFWVO sem o RFWDAO, será necessário identificar como o seu sistema salva as enumerações. Embora existam diversas maneiras de se resolver, se seguir o método do RFWDAO, em que as enumerations são salvas somente pelos seus nomes, ao recuperar o nome do banco de dados e utilizar o ".valueOf()" a operação falhará, já que não sabemos de qual enumeration a unidade pertence.
Para resolver isso o MeasureRuler tem o seguinte método:
MeasureRuler.valueOf(...);
Este método identifica a unidade pelo nome, entre todas as dimensões existentes no MeasureRuler.
![]() |
|
Utilização da Régua
Para realizar a conversão das unidades de medidas devemos focar nos métodos .convertTo(...) da classe MeasureRuler. Há métodos simples utilizados para conversão dentro da mesma dimensão (sem utilização de equivalências) até métodos completos com a entrada de equivalências e definição da precisão de casas decimais.
Exemplos de Utilização
Veja alguns exemplos de utilização da MeasureRuler:
![]() |
Conversão de Unidade de Medida dentro da Mesma Dimensão |
// Converte 1000ml em Litros, retornará um BigDecimal com o valor de 1.000
MeasureRuler.convertTo(new BigDecimal("1000"), VolumeUnit.MILLILITER, VolumeUnit.LITER);
// Converte 1000ml em Litros, mas dessa vez retornará com a precisão de 6 casas decimais.
MeasureRuler.convertTo(new BigDecimal("1000"), VolumeUnit.MILLILITER, VolumeUnit.LITER, 6);
// Converte 1000g em Kilogramas, com uma precisão de 6 casas decimais, retornará o valor 1.000000
MeasureRuler.convertTo(new BigDecimal("1000"), WeightUnit.GRAM, WeightUnit.KILOGRAM, 6);
|
Para converter entre diferentes dimensões (grandezas de medidas diferentes), vamos primeiro estabelecer uma regra de equivalência entre as grandezas, podendo ser feita com qualquer unidade de medida da grandeza.
Vejamos um exemplo, imagine um sistema de marcenaria que precise cadastrar uma chapa de madeira utilizada para móveis. No estoque e durante o processo de compra, referenciamos o item por unidades, pois fica mais fácil de fazer o pedido e comparar preços. Mas no momento de calcular o frete, precisamos saber qual o peso de cada chapa, ou qual o peso final do móvel produzido, de acordo com a "quantidade de chapa" (medida em metros quadrados (área)) que foi recortado e utilizado. Para ter todas essas informações precisamos estabelecer a relação entre as grandezas Unidades, Massa (Peso) e Área.
Imagine que após verificar o produto, descobrimos que a chama tem medida de 2m x 1,8m (=3,6m²), e que ela pesa 76Kg. Assim, montamos nossos dados de equivalência:
![]() |
Criando Regras de Equivalência |
// Regras de Equivalência
MeasureRulerEquivalence eqVO = new MeasureRulerEquivalence();
eqVO.getMeasureUnitHash().put(UnitUnit.UNIT, new BigDecimal("1")); // Definimos que cada 1 Unidade...
eqVO.getMeasureUnitHash().put(WeightUnit.KILOGRAM, new BigDecimal("76")); // equivale a 76Kg...
eqVO.getMeasureUnitHash().put(AreaUnit.SQUAREMETER, new BigDecimal("3.6")); // e a 3,6m²
|
Com as regras de equivalência o 'MeasureRuler conseguirá converter unidades conforme a necessidade. Vamos imaginar que o marceneiro precisa saber quantas chapas vamos precisar para cobrir uma área de 40m². Assim convertemos na régua:
![]() |
Convertendo Entre as Dimensões |
// Chamamos a MeasureRuler, mas agora passando as regras de conversão
BigDecimal v = MeasureRuler.convertTo(eqVO, new BigDecimal("40"), AreaUnit.SQUAREMETER, UnitUnit.UNIT, 6);
// o Valor de v será equivalente a 11.111111, com 6 casas decimais de precisão, conforme solicitado
|
Unidades de Medidas Personalizadas
O MeasureRuler permite que o usuário crie suas próprias unidades de medidas bastando apenas definir um nome e um símbolo. Em uma classe que estenda a interface MeasureUnit. Para que a unidade de medida se torne funcional será ainda necessário estabelecer uma régua de equivalências, explicado no tópico de utilização.
![]() |
|
Estabelecendo Paridade de Conversão - MeasureRulerEquivalenceIntercade
Embora o MeasureRuler já seja capaz de converter unidades de medidas dentro da mesma dimensão, é possível estabelecer equivalências entre as unidades de medidas. Como, por exemplo, estabelecer que 1 unidade tem 50g, e depois disso pedir que a régua converta 1 Dúzia em Kilos.
Essas paridades são definidas apenas implementando a interface MeasureRulerEquivalenceInterface. Nela há apenas um método que deve retornar uma Hash<MeasureUnit, BigDecimal>. A chave da hash é qualquer unidade de medida, e seu valor é um BigDecimal que estabelece o peso da unidade de medida. Exemplos:
- 1 Unidade = 50g = 30ml - Devemos ter os seguintes objetos na Hash:
- hash.put(UnitUnit.UNIT, BigDecimal.ONE);
- hash.put(WeightUnit.GRAM, new BigDecimal("50");
- hash.put(VolumeUnit.MILILITER, new BigDecimal("30");
![]() |
|
Com esses três objetos estabelecemos a referência entre as dimensões Unidades, Massa e Volume. Podendo converter de Toneladas para Centimetros Cúbicos, por exemplo. Para estabelecer, uma referência com uma unidade de medida personalizada basta colocar na Hash a instância da unidade de media personalizada na Hash e estabelecer o seu peso em comparação as demais unidades presentes na Hash.
Validação da MeasureRulerEquivalenceInterface
A classe MeasureRuller contém um método de validação para garantir que as informações da Hash de equivalências não estão redundantes ou incoerentes.