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:
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.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.
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.