Comparar para não parar
Comparar valores é uma tarefa comum dentro do desenvolvimento de software. Estamos o tempo todo comparando informações para tomadas de decisão, desvios de fluxo e outras rotinas dentro dos sistemas.
O acordo
Existe uma forma bem interessante de “comparar” as coisas. Essa forma, é na verdade, uma especie de “acordo” de resultados. Esses valores podem variar entre:
-1, 0 e 1.
Esse conjunto de valores não é uma regra. Espera-se que quando algo é menor que outro, o resultado seja qualquer valor negativo; quando igual, tem que ser zero e quando maior, qualquer valor maior que zero.
Não importa se vamos comparar 5 ou 50.000 valores, só existe uma forma de fazer isso: indo de dois em dois.
As funções implementadas para comparação neste modelo aceitam dois parâmetros de entrada: O valor da “esquerda” e o da “direita“, primeiro e o segundo ou A e o B… Tanto faz! Mais adiante veremos uma implementação desse cenário.
O “acordo” no Delphi: TValueRelationship
O Delphi, assim como outras linguagens, oferece um type para padronização e utilização dessa elegante forma de comparar valores.
O TValueRelationship é um enumerador que parte de -1 até 1, contemplando justamente os valores que precisamos para as comparações (-1, 0 e 1). Declarado na unit System.Types, ele vem acompanhado de três constantes que podem nos auxiliar principalmente na legibilidade do código.
1 2 3 4 5 6 7 |
type TValueRelationship = -1..1; const LessThanValue = Low(TValueRelationship); EqualsValue = 0; GreaterThanValue = High(TValueRelationship); |
A constante LessThanValue representa o “valor de menor que”, utilizando o helper Low que retorna o menor valor dentro da coleção de valores existentes no enumerador TValueRelationship.
A EqualsValue é bastante intuitiva, concorda? Representa o valor de equivalência.
O valor em GreaterThanValue, por sua vez, recebe o maior valor existente no enumerador TValueRelationship através do helper High.
Uma das vantagens de utilização desses 4 elementos combinados, além da legibilidade já citada, é que podemos confiar nos valores atribuídos às constantes sem nos preocuparmos se um dia eles serão alterados.
Um exemplo já implementado
Temos aqui a implementação de uma função nativa do Delphi. Esse método é o CompareDateTime declarado na unit System.DateUtils.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function CompareDateTime(const A, B: TDateTime): TValueRelationship; begin // If the dates are the same, then only compare the time // This returns the correct result for values below the epoch if SameDate(A, B) then begin Result := CompareTime(A, B); end else begin if SameDateTime(A, B) then Result := EqualsValue else if A < B then Result := LessThanValue else Result := GreaterThanValue; end; end; |
É possível perceber claramente o “contrato” nesta implementação onde temos os dois parâmetros de entradas e um Result do tipo TValueRelationship.
Com base nesse padrão de codificação podemos construir funções de comparação genéricas baseadas no mesmo tipo de retorno, gerando um enorme poder de abstração para nossas estruturas. Isso nos impulsiona para um desenvolvimento menos acoplado e cada vez mais abstrato.