13 de dezembro de 2011

Design Patterns com Delphi: Template - Parte I

Criar uma infraestrutura de software é padronizar a forma como as coisas acontececerão dentro de um programa, estabelecendo regras e ditando as mensagens que cada parte do código está preparada para receber. Por exemplo, uma infraestrutura para realizar transações de negócio dentro do sistema pode ser descrita simplificadamente em poucos passos : abertura de transação com o banco de dados; consistência das informações contidas no(s) objeto(s) de negócio envolvido(s); persistência das informações nas respectivas tabelas; encerramento da transação. Todo objeto com capacidade de realizar uma transação terá necessariamente que implementar esses passos.

Se cada Caso de Uso implementar uma versão independente dos passos, mudanças nessa sequência teriam que ser replicadas em todas as implementações. O alvo do Design Pattern comportamental Template é justamente situações como esta, onde um algorítimo é definido de modo centralizado, moldando a forma de trabalho a ser seguida por todas as classes de objeto que desejarem implementá-lo. Um ou mais passos podem ser sobrepostos pelas heranças, permitindo que elas implementem comportamentos diferenciados quando for necessário.

Essa idéia é similar à do Pattern Strategy. A diferença mais importante entre ambos é que o Template permite que heranças alterem partes de um algorítimo enquanto no Strategy temos que optar por uma das versões de um algorítimo bem conhecido e executar todo o trabalho com esse algorítimo.

O quadro a seguir traz um diagrama UML mostrando as relações esperadas entre as classes participantes da solução para o Template. O cenário abordado é o da transação de negócio citado no primeiro parágrafo deste post:
Diagrama UML para o padrão Template
Neste exemplo, nem todos os métodos são virtuais. São declarados como virtuais apenas aqueles que poderão (ou deverão) ter uma implementação distinta nas classes herdadas. Como podemos ver, o algorítimo é decomposto em métodos mais granulares que podem ser sobrepostos quando ncessários. Neste contexto, tais métodos são chamados de operações primitivas.

No exemplo, o método ExecutarTransacao é responsável por chamar cada operação primitiva no tempo correto, moldando efetivamente o algorítimo que deve ser executado por cada classe da hierarquia. Este método é chamado de Template (modelo).

Formalmente, as classes participantes de uma solução para o pattern Template recebem os seguintes nomes:
É denominada Abstract Class a classe base que define as operações primitivas que estarão disponíveis para o algorítimo. Ela também define o esqueleto do algorítimo ao implementar o método Template, chamando cada operação primitiva na ordem correta. No diagrama acima, este é o papel da classe TWTransacao. É importante ressaltar que, apesar do nome, essa classe não precisa ser obrigatoriamente abstrata; se for adequado, a Abstract Class pode prover versões básicas de todas as operações primitivas.

As classes que provêm versões particulares de uma ou mais das operações primitivas são chamadas Concrete Class. Isso permite-lhes realizar ações específicas dentro dos passos básicos que formam o algorítimo determinado pela classe base. No exemplo, as classes TWTrnProduto, TWTrnNotaFiscal e TWTrnPedidoVenda são desse tipo. Elas fornecem suas próprias versões dos métodos que consistem e gravam os dados relativos, respectivamente, às transações para inserir um novo produto, criar uma nota fiscal e criar um pedido de venda.

O Client é qualquer parte do sistema que esteja apta a disparar o algorítimo definido na classe base. A classe TWTela do diagrama de exemplo detem esse papel.
No próximo post, eu apresento uma sugestão de como implementar o exemplo proposto usando Delphi.

Mais Informações
Posts sobre Design Patterns

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.