Classificar dependências por duração e evitar estado de usuário no escopo errado
Artigo · análise e investigação · FundamentosAplicação UniGUI gerada pelo wizard e noções de classes
Delphi 11.3 e 13.2 como referência; confirme a versão do UniGUI e os eventos no seu projetoUma migração de VCL para UniGUI muda uma hipótese importante: vários usuários podem ser atendidos dentro do mesmo processo do servidor. Uma variável que parecia particular ao aplicativo desktop pode passar a ser compartilhada por requisições de pessoas diferentes.
Por isso, antes de decidir onde colocar uma conexão ou um identificador de usuário, pergunte: quem cria esse objeto, quem pode acessá-lo e quando ele deixa de existir?
O mapa de duração
O UniGUI descreve um ServerModule global e um MainModule associado a cada sessão. A arquitetura também inclui os formulários dessa sessão. Confira a documentação da arquitetura UniGUI.
Uma classificação inicial útil é:
| Informação | Duração desejada |
|---|---|
| Configuração pública do serviço | Processo ou configuração externa |
| Identidade autenticada | Sessão, com validação apropriada |
| Seleção temporária de uma tela | Tela ou caso de uso |
| Pedido confirmado | Persistência durável |
| Transação de gravação | Operação de duração limitada |
Essa tabela é uma proposta de desenho. Ela não significa que toda informação deve ser colocada diretamente em um módulo. Um serviço independente pode ser administrado pelo módulo sem misturar as responsabilidades.
MainModule não é um banco de dados
Cada sessão dispõe de sua própria instância de MainModule, que pode acomodar recursos usados por formulários daquela sessão. Referência de MainModule.
Isso torna o módulo um candidato para estado temporário específico do usuário. Não torna seus campos uma forma de armazenamento durável. Se o processo reiniciar, ou se a sessão terminar, uma decisão de negócio já confirmada não deveria depender apenas dessa memória.
Também não guarde uma senha em texto simples só porque ela está em uma sessão. A duração adequada não elimina o problema de sensibilidade da informação.
Modele uma dependência com dono claro
Considere uma classe independente que guarda apenas a seleção corrente de um cliente:
type
TEstadoSelecao = class
private
FClienteID: Integer;
public
procedure Limpar;
property ClienteID: Integer read FClienteID write FClienteID;
end;
procedure TEstadoSelecao.Limpar;
begin
FClienteID := 0;
end;O trecho pode ser colocado em uma unit comum, com declaração e implementação nas seções correspondentes. Ele não utiliza APIs UniGUI. Se o MainModule administrar essa instância, crie-a no evento de criação adequado ao projeto e libere-a no encerramento correspondente. Não misture propriedade por Owner e destruição manual sem verificar o modelo da classe.
Esse estado representa uma seleção, não uma autorização. Antes de consultar ou alterar o cliente, o servidor precisa verificar se a identidade atual pode realizar a operação.
Encerramento também é comportamento
Uma sessão expirada pode coincidir com uma operação demorada. Defina como trabalhos externos serão cancelados ou desassociados e como recursos serão liberados. Uma tarefa não deve continuar acessando um módulo destruído apenas porque foi iniciada por ele.
O comportamento de logout também merece desenho: limpar dados visuais não equivale a revogar credenciais ou encerrar todas as operações. Defina o que a aplicação promete ao usuário e faça essa promessa corresponder ao fluxo do servidor.
Verifique com duas sessões reais
Abra sessões em perfis de navegador distintos ou em uma janela comum e outra privada. Duas abas no mesmo perfil não são, por si só, prova de identidades independentes. Selecione clientes diferentes e compare o estado.
Depois expire uma sessão, encerre o servidor de testes e observe quais dados devem sobreviver. Use uma base isolada: esse roteiro não deve alterar pedidos reais.
Exercício e continuidade
Liste cinco objetos do seu projeto e escreva seu criador, duração, consumidor e responsável por liberar. Se algum campo da tabela ficar indefinido, investigue antes de adicionar novas funcionalidades.
O roteiro não foi executado em uma instalação UniGUI aqui. Avance para Isolamento de dados e concorrência para analisar o que acontece quando duas requisições chegam juntas.
Criação, uso e encerramento
Aplicação → ServerModule compartilhado; sessão → MainModule → formulário → encerramento → liberação dos recursos da sessão.
- Registre objeto, criador e quem libera.
- Owner de componente evita segunda liberação manual; sem Owner, declare a fronteira de limpeza.
- Feche e reabra formulário na mesma sessão; confira estado previsto.
- Teste ação tardia após expiração, sem reutilizar referências destruídas.
Use eventos e IDs sintéticos, nunca cookies. Diagrama conceitual; callbacks, expiração e liberação UniGUI reais dependem do runtime e não foram executados.