À medida que os sistemas se tornam mais complexos, dois problemas surgem: como percorrer coleções de objetos sem expor sua estrutura interna e como evitar que dezenas de classes fiquem acopladas entre si (o famoso “código espaguete”). Além disso, surge a necessidade de salvar o estado de um objeto para restauração futura.
Neste artigo, veremos como o Delphi 13 resolve esses dilemas com padrões que trazem ordem à comunicação e persistência temporária de dados.
1. Iterator: Navegação Padronizada e Abstrata
No desenvolvimento Delphi tradicional, é comum percorrermos listas usando índices (for i := 0 to Count - 1). No entanto, essa abordagem amarra o seu código a uma implementação específica: a de uma lista indexada. O padrão Iterator quebra esse vínculo, permitindo percorrer qualquer coleção de objetos sem expor como eles estão armazenados. O padrão Iterator fornece uma maneira de acessar sequencialmente os elementos de um objeto agregado sem expor sua representação subjacente.
O Problema: Acoplamento e Rigidez de Travessia
Quando você escreve um algoritmo que depende de um índice, você assume que a estrutura de dados permite acesso aleatório rápido.
- O Risco: Se amanhã você precisar trocar um
TObjectListpor umTDictionaryou uma estrutura de árvore (como visto no padrão Composite), todos os seus laços de repetição precisarão ser reescritos. - Impacto no Delphi 13: O código torna-se difícil de refatorar e propenso a erros de “index out of bounds” quando a lógica de filtragem ou ordenação muda.
A Solução: Navegação Polimórfica com IEnumerable
O padrão Iterator propõe o uso de um objeto separado (o Iterador) que conhece a mecânica de navegação da coleção. No Delphi 13, isso é implementado de forma elegante através da interface IEnumerator<T>.
Por que isso transforma sua arquitetura?
- Abstração Total: O seu código de negócio pede um enumerador e consome os dados. Ele não sabe se os dados vêm de um array em memória, de um arquivo TXT ou de uma query SQL paginada.
- Suporte Nativo ao
for-in: Ao implementar o padrão Iterator (via métodoGetEnumerator), sua classe customizada ganha suporte automático ao laçofor-in, tornando o código muito mais limpo e legível. - Iteradores Especializados: Você pode criar múltiplos iteradores para a mesma coleção. Por exemplo, um
TOrdemCronologicaIteratore umTOrdemPrioridadeIterator, permitindo mudar a forma de navegar nos dados apenas trocando o objeto iterador, sem alterar a coleção original.
No Delphi 13, a combinação de Generics com o Iterator permite criar algoritmos de processamento de listas que são completamente independentes do tipo de dado e da estrutura de armazenamento, elevando o nível de reuso do seu framework interno.
A Transição Técnica: No Delphi 13, implementar o GetEnumerator permite que suas classes customizadas funcionem com o laço for-in, escondendo a complexidade da iteração (como pular registros inativos ou filtrar dados em tempo real).
2. Mediator: O Controlador de Tráfego Aéreo
O padrão Mediator define um objeto que encapsula como um conjunto de objetos interage. Ele promove o desacoplamento ao impedir que os objetos se refiram uns aos outros explicitamente.
Implementação Técnica: Reduzindo o Caos em Formulários Complexos
Imagine um formulário com 20 campos, onde o comportamento do Botão Salvar depende do CheckBox A, que limpa o Edit B, que habilita o Combo C.
- Sem Mediator: Cada componente conhece os outros 19. O código fica impossível de manter.
- Com Mediator: Todos os componentes falam apenas com o Mediator. Ele centraliza a lógica de interação.
unit Regys.Patterns.Mediator;
interface
type
IMediator = interface;
// Colega (Componente que interage)
TBaseComponent = class
protected
FMediator: IMediator;
public
constructor Create(AMediator: IMediator);
end;
// A Interface do Mediador
IMediator = interface
procedure Notificar(Sender: TBaseComponent; Evento: string);
end;
// Mediador Concreto
TFormMediator = class(TInterfacedObject, IMediator)
public
procedure Notificar(Sender: TBaseComponent; Evento: string);
end;
implementation
{ TFormMediator }
procedure TFormMediator.Notificar(Sender: TBaseComponent; Evento: string);
begin
if Evento = 'CheckAlterado' then
begin
// Lógica centralizada: se check mudou, desabilita outros campos
end;
end;
end.
3. Memento: A Máquina do Tempo dos Objetos
No quotidiano de um arquiteto Delphi 13, o Mediator e o Memento são as ferramentas que impedem que um formulário se transforme num emaranhado de dependências cruzadas e garantem que o utilizador possa cancelar operações complexas com total segurança.
A. Mediator: O Fim do “Código Esparguete” em Formulários
Em sistemas ERP, é comum termos ecrãs de cadastro com dezenas de componentes que interagem entre si (ex: selecionar um tipo de pessoa habilita o campo CPF ou CNPJ, limpa a Inscrição Estadual e altera o Label da Foto).
- Cenário de Caos: Sem o Mediator, cada componente tem código no seu evento
OnChangeque referencia diretamente outros cinco componentes. Se precisar de remover um campo, o sistema deixa de compilar em múltiplos pontos. - A Solução com Mediator: Todos os componentes notificam apenas o Mediator. Este objeto central contém a inteligência de negócio da interface.
- Vantagem: O formulário torna-se puramente visual. A lógica de “quem habilita quem” fica isolada, facilitando a manutenção e permitindo que a mesma lógica seja reutilizada em diferentes versões do ecrã (VCL e FMX, por exemplo).
B. Memento: Snapshots de Segurança para Edição de Dados
O padrão Memento é a resposta elegante para o botão “Cancelar” em formulários complexos ou assistentes (Wizards).
- Uso Prático: Antes de abrir o ecrã para edição, o objeto de negócio (ex:
TCliente) gera um Memento (um snapshot do seu estado interno atual). Se o utilizador fizer alterações e decidir cancelar, o sistema simplesmente restaura o estado do objeto a partir do Memento. - Diferença para o Undo: Enquanto o Command (Artigo 10) guarda a ação para revertê-la, o Memento guarda o estado. É muito mais eficiente para restaurar um objeto completo após múltiplas alterações rápidas que não precisam de ser desfeitas uma a uma.
C. Mediator para Comunicação entre Frames e Micro-Forms
No Delphi 13, a modularização com TFrame é comum. O desafio é fazer com que o FrameA fale com o FrameB sem que um conheça a existência do outro. O Mediator atua como um barramento de eventos centralizado, onde os Frames se registam para enviar e receber mensagens, mantendo o desacoplamento total exigido por uma Clean Architecture.
D. Memento e Persistência Temporária
O Memento pode ser utilizado para implementar funções de “Auto-save” ou recuperação após falhas. Ao serializar o Memento (em JSON ou Stream) e guardá-lo num cache local, o sistema pode restaurar o trabalho do utilizador exatamente onde ele parou, mesmo que a aplicação tenha sido encerrada inesperadamente, proporcionando uma experiência de utilizador superior.
4. Nuances Técnicas: Performance e Encapsulamento no Delphi 13
Implementar os padrões Iterator, Mediator e Memento no Delphi 13 exige atenção especial ao ciclo de vida dos objetos e ao custo computacional de manter múltiplos estados na memória.
A. Performance de Iteração e o Custo do Enumerador
Ao implementar o padrão Iterator, o Delphi cria um objeto enumerador. Em loops críticos de alta performance:
- Overhead: A criação de um objeto para cada
for-inpode ter um custo pequeno, mas acumulativo. No Delphi 13, o compilador tenta otimizar enumeradores de arrays e listas genéricas, mas para coleções customizadas, certifique-se de que o seuGetEnumeratorretorne uma instância de forma eficiente. - Tipagem: Utilize sempre Generics (
IEnumerator<T>) para evitar o custo de typecasting (RTTI) durante a iteração, garantindo que o compilador possa otimizar o acesso aos dados.
B. Gestão de Memória no Mediator (Referências Circulares)
O Mediator é o centro de uma teia de comunicações. O risco aqui é a Referência Circular: o Mediador conhece os Colegas e os Colegas conhecem o Mediador.
- Solução Técnica: No Delphi 13, utilize o atributo
[Weak]ouIInterfacecom cuidado. Se todos foremTInterfacedObject, a referência mútua impedirá que a contagem de referência chegue a zero, causando um memory leak. - Prática Recomendada: O Mediador deve ser o dono dos colegas, ou os colegas devem ter uma referência fraca para o Mediador.
C. Memento: Custo de Memória e Deep Copy
O padrão Memento armazena o estado do objeto. Se o seu objeto for complexo (contendo outras listas ou objetos internos), você precisará decidir entre:
- Shallow Copy: Copia apenas os valores primitivos e ponteiros (rápido, mas perigoso se o objeto interno mudar).
- Deep Copy (Recomendado): Cria uma cópia completa de toda a árvore de objetos. No Delphi 13, isso pode ser feito via serialização JSON rápida ou Streams de memória.
- Dica de Performance: Para objetos muito grandes, armazene no Memento apenas o “Delta” (o que mudou) em vez do estado completo, economizando memória RAM.
D. Notificações no Mediator e o Risco de Loop Infinito
Em implementações de Mediator, um evento pode gerar uma cadeia de notificações. Se não houver controle, o Componente A notifica o Mediator, que notifica o Componente B, que por sua vez notifica o Mediator novamente, gerando um Stack Overflow.
- Proteção: Utilize flags de estado (ex:
FProcessandoNotificacao: Boolean) dentro do Mediator para ignorar notificações recursivas enquanto uma lógica de atualização já estiver em curso.
E. Resumo
- Iterator e Generics: O uso de
System.Generics.Collectionstorna o Iterator extremamente performático no Delphi 13, permitindo iterações tipadas que evitam o custo de typecasting. - Mediator vs. Eventos: Enquanto o
TNotifyEventé útil para ações simples, o Mediator é superior para fluxos de trabalho, pois centraliza a lógica que estaria espalhada em dezenas de manipuladores de eventos. - Memento e Memória: Guardar snapshots de objetos grandes pode consumir muita memória. No Delphi 13, considere usar o padrão Memento apenas para os dados essenciais ou implemente um limite de estados salvos.
Referências
FLICK, Stefan. Design Patterns with Delphi: Build enterprise-grade applications with modern Delphi and the right design patterns. 1. ed. Birmingham: Packt Publishing, 2024.
GAMMA, Erich; HELM, Richard; JOHNSON, Ralph; VLISSIDES, John. Padrões de Projeto: Soluções reutilizáveis de software orientado a objetos. 1. ed. Porto Alegre: Bookman, 2000.
NOGUEIRA, Rodrigo. Delphi e Clean Architecture: Princípios e práticas para software escalável. 2. ed. São Paulo: Editora Engenharia de Software, 2025.
TEIXEIRA, Marcello. Delphi High Performance: Build fast Delphi applications using concurrency, parallel programming and memory management. 1. ed. Birmingham: Packt Publishing, 2018.
Descubra mais sobre Régys Borges da Silveira
Assine para receber nossas notícias mais recentes por e-mail.
Dê-nos sua opinião, seu comentário ajuda o site a crescer e melhorar a qualidade dos artigos.