Um dos maiores desafios em sistemas de gestão (ERPs) é lidar com regras de negócio que mudam conforme o contexto — como o cálculo de um imposto que varia por estado ou o envio de notificações que devem ocorrer sempre que um estoque atinge o nível crítico.
Neste artigo, veremos como o Strategy nos permite trocar algoritmos em tempo de execução e como o Observer estabelece uma comunicação desacoplada entre objetos no Delphi 13.
1. Strategy: Algoritmos Intercambiáveis
No desenvolvimento de software corporativo, é comum encontrarmos métodos que tentam prever todas as variações de uma regra de negócio. O padrão Strategy ataca diretamente o acoplamento causado por essas decisões centralizadas, encapsulando cada variação em uma classe separada e tornando-as intercambiáveis.
O Problema: O “Método Deus” e a Rigidez Algorítmica
Imagine um sistema de faturamento que precisa calcular o imposto de acordo com o estado ou o tipo de produto.
- Modo Antigo: Um método
CalcularImpostocontendo umcaseou uma sequência deifcom centenas de linhas. - Impacto no Delphi 13: Cada vez que uma alíquota muda ou um novo estado é adicionado, você precisa alterar o código core do sistema, recompilar e realizar testes de regressão em todo o módulo. Isso viola o Princípio Aberto/Fechado (OCP), que dita que uma classe deve estar aberta para extensão, mas fechada para modificação.
A Solução: Injeção de Algoritmos
Com o Strategy, definimos uma interface comum (ex: IImpostoStrategy) e implementamos cada regra em sua própria unidade (ex: TImpostoICMS, TImpostoISS).
Por que isso transforma seu código?
- Isolamento de Responsabilidade: O objeto de negócio (Contexto) não sabe como o cálculo é feito, apenas o que deve ser feito.
- Extensibilidade sem Risco: Para adicionar uma nova regra, basta criar uma nova classe que implemente a interface. O código existente permanece intocado e seguro.
- Facilidade de Testes: Você pode testar cada estratégia de forma isolada através de testes unitários, garantindo que o cálculo de “ICMS” esteja correto sem precisar processar uma venda completa.
No Delphi 13, a combinação de Strategy com Dependency Injection (DI) permite que o sistema decida, em tempo de execução (via configuração ou metadados), qual algoritmo deve ser injetado no motor de regras, conferindo uma flexibilidade sem precedentes à aplicação.
2. Observer: Comunicação Orientada a Eventos
O padrão Observer define uma dependência um-para-muitos entre objetos, de modo que quando um objeto muda de estado, todos os seus dependentes são notificados e atualizados automaticamente.
Implementação Técnica: O “Publisher-Subscriber” no Delphi 13
No Delphi, o Observer é a alternativa profissional aos eventos (TNotifyEvent) quando você precisa que múltiplos interessados reajam a uma única mudança.
unit Regys.Patterns.Observer;
interface
uses System.Generics.Collections, System.SysUtils;
type
// 1. O Contrato do Observador
IObserver = interface
['{D1E2F3A4-B5C6-4789-A0B1-C2D3E4F5A6B7}']
procedure Update(const AMsg: string);
end;
// 2. O Sujeito (O objeto que será observado)
TEstoque = class
private
FObservadores: TList<IObserver>;
FQuantidade: Integer;
public
constructor Create;
destructor Destroy; override;
procedure Adicionar(AObserver: IObserver);
procedure MudarQuantidade(const ANovaQtd: Integer);
end;
implementation
{ TEstoque }
constructor TEstoque.Create;
begin
FObservadores := TList<IObserver>.Create;
end;
procedure TEstoque.Adicionar(AObserver: IObserver);
begin
FObservadores.Add(AObserver);
end;
procedure TEstoque.MudarQuantidade(const ANovaQtd: Integer);
begin
FQuantidade := ANovaQtd;
// Notifica todos os interessados
for var LObserver in FObservadores do
LObserver.Update('Estoque alterado para: ' + IntToStr(FQuantidade));
end;
destructor TEstoque.Destroy;
begin
FObservadores.Free;
inherited;
end;
end.
3. Aplicação no Dia a Dia: Regras de Negócio e Interfaces Reativas
No quotidiano de um programador Delphi 13, o Strategy e o Observer são os alicerces para evitar que o código se torne um “legado difícil” em poucos meses. Eles permitem que o software cresça organicamente, respondendo a mudanças legislativas e de interface com o mínimo de impacto.
A. Strategy: Motores de Impostos e Promoções Dinâmicas
Um dos cenários mais críticos em ERPs é a volatilidade das regras fiscais e comerciais.
- Cenário de Uso: Imagine um motor de descontos onde, hoje, o desconto é fixo, mas amanhã pode ser progressivo ou baseado na fidelidade do cliente.
- A Transição Clean: Em vez de poluir a classe
TVendacom lógica de descontos, você injeta umIDescontoStrategy. - Vantagem: O sistema pode escolher a estratégia em tempo de execução com base no perfil do cliente ou numa configuração do banco de dados, sem que a classe de Venda precise de um único
ifadicional.
B. Observer: Sincronização de UI e Micro-Serviços Internos
O Observer é a solução profissional para quando uma ação num ponto do sistema precisa de gerar uma “onda” de reações em outros módulos.
- Exemplo Real: Num sistema de vendas, quando um
StatusPedidomuda parafaturado:- A UI precisa de atualizar a cor na grelha.
- O módulo de Logística precisa de gerar a guia de remessa.
- O módulo de CRM precisa de enviar um WhatsApp ao cliente.
- Implementação no Delphi 13: O objeto
TPedidonão conhece a Logística nem o CRM. Ele simplesmente notifica os seus observadores. Cada módulo “inscreve-se” para observar o pedido, garantindo um desacoplamento total.
C. Strategy para Exportação e Integração (Gateways)
Se o seu sistema precisa de enviar dados para diferentes destinos (Arquivo TXT, API REST, JSON), utilize o Strategy. Defina a interface IExportStrategy. O seu código de exportação foca em quais dados enviar, enquanto as estratégias concretas focam no formato e no protocolo, facilitando a adição de novos destinos no futuro.
D. Observer para Auditoria e Logs (LGPD)
Com a necessidade de conformidade com a LGPD, o Observer pode ser usado para monitorizar alterações em campos sensíveis. Um TAuditoriaObserver pode observar as suas classes de domínio e, sempre que um método de alteração de dados for chamado, ele regista quem, quando e o que foi alterado, de forma totalmente transparente para a lógica de negócio principal.
4. Nuances Técnicas: Performance e Gerenciamento de Memória no Delphi 13
Implementar os padrões Strategy e Observer no Delphi 13 exige mais do que apenas criar classes; exige maestria no ciclo de vida dos objetos para evitar os temidos vazamentos de memória e garantir que a reatividade não comprometa a estabilidade da aplicação.
A. O Ciclo de Vida do Observer e o “Assinante Fantasma”
O maior risco do padrão Observer no Delphi é o vazamento de memória ou violação de acesso (Access Violation). Se um observador (Interface) for destruído mas o sujeito ainda mantiver uma referência para ele em sua lista interna, o sistema tentará notificar um objeto que não existe mais.
- Solução Moderna: No Delphi 13, utilize
TList<IInterface>para armazenar os observadores. A contagem de referência (ARC) garante que o objeto não será destruído enquanto estiver na lista. - Prática Sênior: Mesmo com interfaces, é recomendável implementar um método
Remover(AObserver)e garantir que o observador se “desinscreva” no seudestructorou no eventoOnClosede um formulário, mantendo o controle total sobre o fluxo.
B. Performance e Polimorfismo no Strategy
O Strategy baseia-se em chamadas de métodos virtuais através de interfaces. No Delphi 13, isso introduz uma pequena indireção na tabela de métodos virtuais (VMT).
- Impacto Real: Para 99% das regras de negócio (cálculos fiscais, validações, etc.), esse custo é medido em nanosegundos e é irrelevante.
- Otimização: Em loops de altíssima performance (ex: processamento de milhões de registros em memória), prefira injetar a estratégia antes do início do loop, evitando que o código de decisão (qual estratégia usar) seja executado repetidamente dentro da iteração.
C. Observer e a Reatividade Multithread
Em aplicações modernas que utilizam TTask ou TThread, o sujeito pode notificar alterações a partir de uma thread secundária.
- O Perigo: Se um observador for um componente de UI (um
TLabelouTGrid), tentar atualizá-lo diretamente de uma thread secundária causará instabilidade ou travamento. - A Abordagem Delphi 13: Utilize
TThread.QueueouTThread.Synchronizedentro do métodoUpdatedo observador para garantir que a atualização da interface ocorra sempre na Main Thread, mantendo a aplicação fluida e segura.
D. Estratégias Estáticas vs. Dinâmicas
No Delphi 13, você pode otimizar o Strategy usando Anonymous Methods para estratégias muito simples, evitando a criação de uma unidade inteira para uma lógica de poucas linhas. Contudo, para regras complexas, a abordagem baseada em classes continua sendo a melhor escolha para manter a testabilidade e o desacoplamento.
E. Problemas Comuns
- Memory Leaks no Observer: Este é o maior risco. Se um Observador (Interface) for destruído mas o Sujeito ainda o tiver na lista, você terá problemas. No Delphi 13, o uso de
TList<IInterface>resolve isso, pois a referência cai para zero e o objeto é limpo. Contudo, é boa prática o observador se “desinscrever” no seuDestroy. - Inlining no Strategy: Como o Strategy faz chamadas polimórficas (virtuais), o compilador não consegue fazer o inline do código. O impacto é mínimo, mas em loops de milhões de iterações (processamento de imagem, por exemplo), isso deve ser considerado.
- Observer Thread-Safe: Se o Sujeito for alterado em uma thread secundária, lembre-se de que os Observadores de UI devem usar
TThread.SynchronizeouTThread.Queueao processar a atualização.
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.