Conversor de unidades: Temperatura

Prev Next

To download the app, visit: [tulip](https://<span translate=).co/library/apps/unit-converter--temperature/">Library

Neste artigo, um de nossos desenvolvedores da biblioteca, Tamás, explica as decisões de desenvolvimento por trás do aplicativo “Conversor de Unidades: Temperatura”, disponível na biblioteca.

Por que usei uma lista de objetos em vez de uma tabela

Olá, sou o Tamás, da Tulip.

Para este componente, decidi usar uma lista de objetos armazenada como valores padrão de variáveis, pois o conjunto de dados raramente muda e não requer gerenciamento baseado em tabela.

Nesse caso, os fatores de conversão de temperatura e os deslocamentos são relações matemáticas estáticas. Eles não exigem edição em tempo de execução, agregação ou consultas relacionais. Por isso, evitei deliberadamente usar uma tabela. Em vez disso:* Armazeno as definições de conversão dentro de uma variável* A variável é inicializada com valores padrão* A lista de objetos oferece uma visualização de dados estruturada e legível* Não é necessária nenhuma lógica de agregação de tabela

Essa abordagem mantém o componente leve e autônomo.

Por que não uma tabela?

Usar uma tabela introduziria:* A necessidade de adicionar uma tabela adicional ao aplicativo* A necessidade de criar uma consulta para essa tabela* A necessidade de configurar a lógica de agregação para essa consulta* A necessidade de adicionar e manter essa consulta e agregação dentro do aplicativo também

Para um conjunto de dados que raramente muda, essa sobrecarga é desnecessária.

Ao armazenar as definições de conversão como valores padrão dentro de uma variável:* O componente se torna totalmente portátil* Ao copiar o aplicativo, a estrutura de dados também é copiada* Não é necessária nenhuma dependência externa

A lista de objetos oferece uma visão clara e estruturada dos atributos relacionados (inputUnit-targetUnit, fator, deslocamento) sem exigir lógica relacional.

Princípio de Design: Lógica Protegida, Configuração Flexível

O componente foi projetado com um princípio fundamental:

A lógica central nunca deve exigir modificações.

Para garantir isso, introduzi variáveis internas do componente e as marquei com um sublinhado inicial (por exemplo, _temperatureInputUnit). Essas variáveis com sublinhado atuam como interfaces internas estáveis nas quais a lógica central protegida pode se basear.

Compromisso: o uso de variáveis internas requer dois pequenos gatilhos de configuração:* 01 – CONFIGURAÇÃO DO USUÁRIO: ESTÁGIO DE ENTRADA mapeia fontes externas para variáveis internas* 03 – CONFIGURAÇÃO DO USUÁRIO: ESTÁGIO DE SAÍDA mapeia o resultado interno para o destino desejado

Isso adiciona uma fina camada de configuração ao redor do mecanismo protegido, mas mantém o gatilho MAGIC inalterado e fácil de copiar e colar.

Opção alternativa

Uma abordagem mais simples — mas menos sustentável — seria colar referências externas diretamente na expressão central (por exemplo, usando uma variável de aplicativo ou um placeholder table record field inline).

Isso evita os gatilhos de configuração extras, mas reduz a portabilidade e dificulta a reutilização, pois cada cópia exige a edição da lógica central.

Para a distribuição de componentes, o padrão de interface de variáveis internas é mais fácil de gerenciar: entradas e saídas são configuradas nas bordas, enquanto o mecanismo de cálculo permanece estável e protegido.

O gatilho MAGIC realiza uma consulta e aplica uma transformação afim:

resultado = (valor × fator) + deslocamento

Como as definições de conversão estão centralizadas na lista de objetos internos, o gatilho pode lidar com vários casos sem modificação.

Nesta implementação:* °C, K e °F são suportados* Todas as combinações 3×3 são predefinidas* A lógica determina dinamicamente o fator e o deslocamento corretos

O desenvolvedor do aplicativo precisa apenas:1. Configurar as fontes de entrada2. Configurar o destino de saída

Sem reescrever fórmulas. Sem editar lógica condicional. Sem alterações estruturais.

Por que isso é escalável

Essa estrutura permite:* Adicionar novas unidades por meio da extensão da lista de objetos* Manter o mecanismo de cálculo inalterado* Manter a consistência arquitetônica entre os aplicativos* Reutilização rápida em vários projetos

O componente separa:* Configuração da fonte de dados (Estágio de Entrada)* Lógica de execução (MAGIC)* Roteamento do resultado (Estágio de Saída)

Essa separação mantém o sistema seguro, previsível e escalável.

Análise do gatilho – Como o MAGIC (expressão) funciona

O gatilho MAGIC protegido é implementado como uma única expressão:(@Variable._temperatureInputValue * array_value_at_index( map_to_number_list(@Variable._temperatureConversionDefaults , 'factor'), array_index_of( map_to_text_list(@Variable._temperatureConversionDefaults , 'inputUnit-targetUnit'), @Variable._temperatureInputUnit + '-' + @Variable._temperatureTargetUnit )))+array_value_at_index( map_to_number_list(@Variable._temperatureConversionDefaults , 'offset'), array_index_of( map_to_text_list(@Variable._temperatureConversionDefaults , 'inputUnit-targetUnit'), @Variable._temperatureInputUnit + '-' + @Variable._temperatureTargetUnit ))Em linhas gerais, essa expressão executa três etapas:

1. Construir a chave de pesquisa

A chave é construída dinamicamente a partir das variáveis de entrada configuradas:

unidadeDeEntrada-unidadeDeDestino

Por exemplo:

°C-°F

Isso garante que a lógica permaneça genérica e funcione para todas as combinações suportadas.

2. Resolver o fator e o deslocamento a partir da lista de objetos

A expressão determina o fator e o deslocamento em uma única etapa:* map_to_text_list(..., 'unidade_de_entrada-unidade_de_destino') cria a lista de chaves de pesquisa dinamicamente.* array_index_of(...) encontra o índice da chave correspondente.* array_value_at_index(...) usa esse índice para extrair os valores correspondentes das listas de fator e deslocamento.

A principal escolha de design aqui é compor array\_index\_of(...) diretamente com map\_to\_text\_list(...). Isso evita o armazenamento de uma lista intermediária de chaves em uma variável separada. Em vez disso, a lista de pesquisa é gerada inline e imediatamente usada para recuperar tanto o fator quanto o deslocamento em uma única expressão.

Isso mantém o gatilho MAGIC autônomo e reduz a área de configuração, ao mesmo tempo em que continua se comportando como uma consulta estruturada — sem exigir uma tabela ou lógica de agregação.

3. Aplicar a transformação afim

Assim que o fator e o deslocamento corretos forem determinados, o cálculo é aplicado:

resultado = (valor × fator) + deslocamento

Como a lógica de consulta é baseada em índices e orientada por dados, o gatilho não requer ramificações condicionais nem estruturas do tipo switch-case.

Por que essa estrutura foi escolhida

  • Ela evita lógica condicional codificada de forma rígida.
  • Ela se adapta naturalmente quando novas combinações de unidades são adicionadas.
  • Mantém o cálculo totalmente orientado por dados.
  • Ela mantém uma única expressão protegida em vez de vários gatilhos.

Esse projeto mantém o componente determinístico, extensível e protegido contra modificações acidentais na lógica.

Ampliação com novas unidades

Para adicionar uma nova unidade, amplie _temperatureConversionDefaults adicionando uma nova entrada que inclua:* inputUnit-targetUnit (chave)* fator* deslocamento

Assim que o novo mapeamento existir na lista de objetos, o gatilho MAGIC protegido poderá resolvê-lo automaticamente — não são necessárias alterações na lógica central.

Tratamento de falhas (padrão de consulta segura)

O gatilho MAGIC inclui detecção explícita de falhas para garantir a execução segura quando um par de conversão não é encontrado. Em vez de depender de um resultado em branco, o gatilho verifica o índice de pesquisa diretamente:

ARRAY_INDEX_OF( MAP_TO_TEXT_LIST(_temperatureConversionDefaults, 'inputUnit-targetUnit'), _temperatureInputUnit + '-' + _temperatureTargetUnit )

Se o índice retornado for igual a -1, não existe nenhuma regra de conversão correspondente.

Fluxo de execução: 1. Limpe _temperatureConversionResult no início do gatilho. 2. Se o índice de pesquisa = -1 → não calcule. 3. Caso contrário → calcule e armazene o resultado.

O estágio OUTPUT verifica então:

Se _temperatureConversionResult estiver em branco → exibir mensagem de erro.

Exemplo de mensagem:

“Nenhuma regra de conversão encontrada para o par de unidades selecionado. Verifique o formato da unidade (°C, K, °F) e se o par existe em _temperatureConversionDefaults.”

Isso garante:• Que não permaneçam valores desatualizados de execuções anteriores • Que nenhum cálculo seja tentado sem uma regra válida • Que o usuário receba uma mensagem de erro clara e que permita ação

A lógica central permanece protegida e inalterada, ao mesmo tempo em que oferece um comportamento determinístico e seguro.

Por que não usar matrizes separadas para chaves, fatores e deslocamentos?

Uma abordagem alternativa teria sido armazenar:* As chaves de pesquisa em um array* Os fatores em outro array* Os deslocamentos em um terceiro array

Embora isso funcionasse tecnicamente, introduziria um risco estrutural: a relação posicional entre as matrizes deve permanecer sempre perfeitamente alinhada.

Se a ordem de um array mudar e a dos outros não, a relação chave–fator–deslocamento seria quebrada silenciosamente, produzindo conversões incorretas.

Ao armazenar atributos relacionados juntos em uma lista de objetos, cada entrada mantém seus valores de inputUnit-targetUnit, fator e deslocamento agrupados logicamente. Isso reduz o risco de desalinhamento e torna a estrutura mais segura e fácil de manter.

Participe

Junte-se à comunidade para compartilhar melhorias, propor unidades adicionais, relatar problemas ou discutir decisões arquitetônicas.