CS Coder
UniGUI

Formulários UniGUI menores: organize o evento em torno de um caso de uso

Tire cálculo e persistência dos eventos sem criar camadas vazias. Use uma função independente como primeiro passo para um formulário mais claro.

· 4 min de leitura
Objetivo e formato

Separar leitura da tela, cálculo e apresentação do resultado

Tutorial · prática orientada · Intermediário
Antes de experimentar

Eventos de formulários e units Delphi

Unit principal compilada e exercitada com DCC32 37.0, build 37.0.59082.6021. Referência editorial: Delphi 11.3 e 13.2; essas duas versões não foram verificadas individualmente.

Documentação, instalação e limites de Fundamentos em seis units

Um evento OnClick começa pequeno. Depois ganha validação, leitura de banco, cálculo, log e atualização de vários controles. O problema aparece quando outra tela precisa da mesma regra e a alternativa mais rápida parece copiar o evento.

Vamos separar um cálculo de duração entre horários. O cenário é um agendamento, mas a função não conhecerá formulário, navegador ou banco de dados.

Defina o caso de uso em linguagem simples

A necessidade inicial é: receber início e fim válidos e devolver a duração em minutos. Antes de escolher classes, defina os limites: fim anterior ao início é inválido; horários iguais representam duração zero.

O exemplo trabalha com dois TDateTime na mesma referência temporal. Ele não resolve fusos, horários de verão ou agendamentos que atravessam mudanças de offset. Isso precisa de um contrato específico numa aplicação real.

Extraia a regra para uma unit

Crie Agenda.Duracao.pas:

delphi
unit Agenda.Duracao;

interface

function DuracaoEmMinutos(const Inicio, Fim: TDateTime): Double;

implementation

uses
  System.SysUtils;

function DuracaoEmMinutos(const Inicio, Fim: TDateTime): Double;
begin
  if Fim < Inicio then
    raise EArgumentException.Create('Fim anterior ao início');
  Result := (Fim - Inicio) * 24 * 60;
end;

end.

A saída é Double porque pode haver fração de minuto. Arredondar para minutos inteiros exige outra decisão: arredondar para cima, para baixo ou para o mais próximo produz comportamentos diferentes. Não esconda essa regra dentro de uma formatação.

Deixe o evento traduzir a interação

No formulário, o evento pode ler valores dos controles, chamar DuracaoEmMinutos e mostrar a saída. A mensagem visual pode tratar EArgumentException de maneira compreensível. Falhas inesperadas devem seguir o mecanismo de diagnóstico da aplicação.

text
Evento do formulário
  → converte entradas visuais
  → chama cálculo/caso de uso
  → apresenta resultado ou problema de entrada

Evite levar a função de volta ao formulário para atualizar labels. Se o cálculo passa a salvar o agendamento, essa gravação deve ter autorização e uma transação definida, em vez de SQL espalhado pelo evento.

A separação ajuda a testar e também a enxergar o que acontece no servidor. UniGUI atende múltiplas sessões; o acesso aos formulários e módulos precisa respeitar o contexto de sessão descrito na arquitetura oficial.

Não crie serviços sem responsabilidade

Uma classe que apenas chama outra classe e não expressa nenhuma fronteira pode aumentar a navegação sem melhorar o desenho. Para este cálculo puro, uma função é suficiente.

Uma classe de caso de uso se torna útil quando precisa coordenar dependências e um comportamento definido: verificar autorização, carregar dados, aplicar a regra e persistir o resultado. Não confunda essa coordenação com uma nova pasta.

Teste sem sessão web

Num projeto de console, construa horários usando EncodeDate e EncodeTime. Confira duração zero, trinta minutos e uma hora. Para fim anterior ao início, a expectativa é uma exceção.

Como o cálculo usa ponto flutuante, compare valores com uma tolerância definida, não apenas com igualdade literal em todos os cenários. Teste também segundos quando seu contrato permitir precisão abaixo de um minuto.

A unit foi compilada; duração zero, 30 minutos, 60 minutos e intervalo negativo passaram no projeto de verificações. A integração visual ainda precisa ser exercitada. Ao integrar, teste o evento no navegador e confirme que uma entrada inválida não executa a gravação.

Desafio e continuidade

Acrescente uma regra de duração máxima configurável. Escreva primeiro os exemplos de entrada e os resultados esperados. Decida se ultrapassar o máximo rejeita o agendamento ou apenas gera um aviso: a função não deve inventar essa política.

Para separar coordenação e regra, leia Tela, serviço e domínio.

Wiring do exemplo de duração

Controles início/fim → conversão TDateTime → Agenda.Duracao.DuracaoEmMinutos → saída visual.

  1. Leia e converta os valores no evento.
  2. Passe valores à função, não componentes.
  3. Traduza EArgumentException para erro junto dos campos.
  4. Teste zero, 30 minutos e fim anterior no console antes de ligar o formulário.

O desafio corresponde à duração usada no artigo. Estado de sessão precisa de dono; singleton global não deve guardar usuário. Console disponível; wiring UniGUI e versão instalada não executados nesta revisão.

Agora é com você

Duas sessões podem acabar compartilhando dados de um usuário?

Escolha um evento de formulário e identifique nele a interação visual, a regra de negócio e o acesso a dados. Esboce como separá-los e quem deve ser dono do estado de sessão.

Ver uma pista para começar

Revise variáveis globais e o ciclo de vida dos módulos. Separe o estado de cada usuário e verifique autorização no servidor, mesmo quando a interface oculta uma ação.

Não precisa acertar de primeira. Observe o resultado e explique o que mudou.

Leitura relacionada

Outra conexão para investigar

Use uma política de limite de itens para distinguir entrada visual, regra e coordenação, com um exemplo independente de VCL, FMX e UniGUI.

Tela, serviço e domínio: separe decisões sem transformar tudo em camadas ↗

4 min de leitura

Abrir projeto de exemplo ↗