Já comentei aqui no blog a respeito dos Design Patterns
Criacionais (relativos à forma como os objetos são criados num programa) e dos
Estruturais (que abordam as associações estruturais entre classes e objetos, isto é, os relacionamentos entre as classes para garantir a coesão de um projeto). Ficaram faltando ainda os Design Patterns
Comportamentais, que são aqueles que se preocupam com as interações existentes entre objetos. Essas interações devem ser concebidas de maneira que os objetos possam trocar mensagens entre si (se comunicar) e ainda assim permanecerem fracamente acoplados, isto é, sem que uns tenham dependências rígidas com os outros ou que tenham que conhecer detalhes profundos da implementação uns dos outros.
O primeiro desses padrões que tratarei aqui é
Cadeia de Responsabilidade. Nele, a requisição feita por um objeto Cliente é transmitida ao longo de uma sequência de Classes até que a requisição seja suprida por uma delas. Como a ideia é manter as classes o mais desacopladas possível, esse tipo de transmissão da mensagem (requisição) é baseado no conceito de "orientação a dados", ou seja, a estruturação dos dados trafegados na mensagem é o único ponto de contato entre as classes. Aquela Classe que recebe a mensagem deve analisar os dados recebidos e, se não for capaz de atender à requisição, ela deverá retransmitir a mensagem para o objeto seguinte na hierarquia.
Exemplos típicos da aplicação do padrão
Cadeia de Responsabilidade envolvem alçadas de aprovação. Imagine, por exemplo, o sistema de compras de uma companhia, onde os Compradores podem submeter os pedidos de compra sem necessitar uma aprovação se o pedido tiver certas características (digamos, um limite máximo de valor) mas que, conforme estas características vão variando, o pedido deve ser submetido a aprovação por níveis hierárquicos cada vez mais altos (supervisor, gerente, diretor, presidente).
O diagrama abaixo mostra as classes participantes da solução para esse cenário utlizando a
Cadeia de Responsabilidade.
A nomenclatura das classes participantes da solução é descrita no quadro abaixo:
Handler é a classe que descreve a interface que é disponibilizada para aqueles que pretendem submeter uma requisição. Ou seja, é uma classe abstrata que apenas oferece os pontos de entrada para as requisições que poderão ser feitas; as transações que forem utilizá-la não saberão de antemão quais nem quantos são os níveis hierárquicos existentes, tampouco as regras aplicadas. No diagrama acima, este é o papel da classe
TWAprovacao.

É preciso que outras classes sejam criadas para implementar a interface publicada pelo Handler. Essas classes são chamadas de
Concrete Handlers, sendo exemplos as classes
TWAprovacaoBasica e
TWAprovacaoGerente no diagrama. Repare que apenas observando o diagrama não é possível determinar a hierarquia da cadeia de responsabilidades. Isso terá que ser montado através de algum dos
padrões criacionais, num ponto em que inevitavelmente teremos que introduzir regras de negócio.

Por fim, a classe que submete uma requisição à Cadeia de Responsabilidades é chamada de
Client. A classe
TWbusinessObj tem essa função no nosso exemplo.
A classe
TWDocumento representa um documento genérico do meu sistema, podendo ser um Pedido de Compra ou de Venda, uma Nota Fiscal, etc.. Ela é o ponto de contato entre a transação representada pelo objeto de negócio
TWbusinessObj e a hierarquia de classes da Cadeia de Responsabilidade. Portanto, neste exemplo o
TWDocumento é o dado que trafega pelos elos da cadeia permitindo que cada classe tenha subsídios para determinar se a mensagem é de sua responsabilidade ou se ela deve ser retransmitida.
No próximo post eu apresento uma forma de codificar essa solução usando Delphi.
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.