Certas tarefas em um sistema computacional podem ser implementadas de diferentes maneiras sem que isso afete o resultado final esperado. Isto é, partindo de um determinado contexto, podemos selecionar um algoritmo entre vários possíveis e atingir o mesmo objetivo com qualquer um deles. Por exemplo, dada uma lista que precisa ser ordenada, há diversos
algoritmos de ordenação que podem realizar a tarefa, como o método da bolha,
quick sort ou busca binária. Independentemente do algoritmo escolhido, ao final do processo teremos a lista classificada. É claro que há diferenças de performance de um método pra outro mas isso é parte do processo de escolha daquele que melhor se adapta a uma situação. Cada situação encontrada pode levar a uma escolha distinta, sem que uma seja necessariamente preferida em relação às outras.
O programa pode, então, ter que intercambiar dinamicamente o algoritmo, seja por opção explícita do usuário ou por causa de outras questões circunstanciais encontradas durante a execução. Em projetos orientados a objetos, podemos desenhar uma solução para esse tipo de cenário usando o
Design Pattern comportamental Strategy.
O objetivo do
Strategy é permitir que o programa utilize de forma transparente qualquer algoritmo capaz de realizar uma determinada tarefa, construindo para isso uma estrutura de classes com baixo acoplamento. Com isso, fica fácil adicionar novos algoritmos, enquanto os códigos que os utilizarão continuam independentes da escolha feita.
Num sistema real, essa solução pode ser aplicada, por exemplo, no pagamento de títulos. Considere que um título pode ser pago levando o respectivo boleto ao banco, cadastrando a conta como débito automático ou registrando o pagamento no
Internet Banking. Qualquer que seja a forma selecionada, o resultado é o título pago. O diagrama
UML abaixo mostra as classes e suas relações para o
Strategy aplicado a este cenário:
A nomenclatura formal para as classes que participam da solução com o
pattern Strategy é a seguinte:

A classe
Strategy é uma interface onde é definido o comportamento comum a ser respeitado por todos os algoritmos. Em outras palavras, devemos incluir nesta classe funções virtuais (e provavelmente abstratas) que fixarão a forma com que a tarefa estará acessível às outras partes do programa. A classe
TWPagamento do diagrama acima exerce esse papel, definindo que pagamentos deverão ser feitos através da função
efetuaPgto.

São chamadas de
Concrete Strategy as classes que atendem a definição introduzida no
Strategy e que, portanto, implementam um algoritmo que efetivamente realize a tarefa proposta. No diagrama, esse papel cabe a três classes distintas :
TWPgtoBoleto,
TWPgtoDebitoAuto e
TWPgtoInternete. Cada uma delas executará a tarefa a sua maneira, providenciando uma versão própria da função
efetuaPgto.

O
Context é a classe que usará o comportamento definido pela
Strategy, invocando as funções disponibilizadas por ela. Portanto, o
Context deverá armazenar internamente uma referência ao
Strategy. Em geral, ele também terá que expor formas de interagir com o
Strategy, publicando propriedade e funções. No nosso exemplo, o
Context é a classe
TWTitulo; a interação com o
Strategy é conseguida passando-se para a tarefa uma instância do próprio título a ser pago.

Um
Client é qualquer parte do sistema que solicite uma operação à classe
Context. Esse tipo de classe foi omitido do diagrama.
No próximo post, mostro uma sugestão de como implementar na prática essa solução usando o Delphi.
2 comentários :
Boa tarde. Primeiramente parabéns pelo blog. Gostaria de saber qual ferramenta usa pra desenhar os diagramas.
Blogueiro
Os diagramas foram criados com o Microsoft Visio. É uma ferramenta genérica para desenho mas que possui plugins (chamados de stencil) para criar vários tipos de diagramas UML.
[]s
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.