Java Dzone (2) |
GOF: Avoid coupling the sender of a request to its receiver by giving more than one
object a chance to handle the request. Chain the receiving objects and pass the
request along the chain until an object handles it.
Tradução livre: Evitar acoplar o enviador da requisição com o recebedor (objeto que irá tratar a requisição) , dando a oportunidade de mais de um objeto tratar esta requisição. Encadeie os recebedores e passe a requisição por essa cadeia até que algum recebedor trate.
Quando utilizar?
- Quando você deseja que a requisição seja interceptada e tratada por mais de um objeto, e estes objetos sejam escolhidos em tempo de execução.
Consequências:
- Reduz acoplamento: Não acopla o enviador com o recebedor. O recebedor não sabe da existência de outros recebedores.
- Adiciona flexibilidade: Pode-se adicionar recebedores e retirar recebedores em tmepo de execução.
- Não há garantia que algum recebedor intercepte algum objeto.
Geralmente este padrão é utilizado com o padrão Composite.
Exemplo:
Utilizando-se do exemplo de Email do Java Dzone (2), vou exemplificar o uso deste padrão.
O sistema irá receber um email e dependendo do email, ele deverá passar um tratamento. No caso deste exemplo, o "tratamento" é simplismente um print na tela.
Nossa classe Email, que iŕa conter o email propriamente dito.
public class Email { private String from; public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } }
A interface EmailHandler, define dois métodos que as classes concretas deverão implementar. No caso o método setNext, indica a próxima classe que deverá tratar a requisição, criando assim uma cadeia de objetos.
public interface EmailHandler { public void setNext(EmailHandler next); public void handleRequest(Email email); }
A classe AbstractEmailHandler implementa a classe EmailHandle. O método handleRequest irá verificar se o email é do tipo que deve ser interceptado, caso for, o método doHandle fará o tratamento, caso não for, passa para o próximo objeto da cadeia se existir, caso não exista a interceptação acaba. Cuidado que seu objeto no final pode não ser interceptado.
public abstract class AbstractEmailHandler implements EmailHandler{ private EmailHandler next; public final void setNext(EmailHandler next){ this.next = next; } public final void handleRequest(Email email){ if(accept(email)){ doHandle(email); }else if(this.next != null){ this.next.handleRequest(email); } } public abstract boolean accept(Email email); public abstract void doHandle(Email email); }
Classes concretas que estendem AbstractEmailHandler
public class GmailHandler extends AbstractEmailHandler{ @Override public boolean accept(Email email) { return email.getFrom().endsWith("@gmail.com"); } @Override public void doHandle(Email email) { System.out.println("Email Gmail = " + email.getFrom()); } }
public class HotmailHandler extends AbstractEmailHandler{ @Override public boolean accept(Email email) { return email.getFrom().endsWith("@hotmail.com"); } @Override public void doHandle(Email email) { System.out.println("Email Hotmail = " + email.getFrom()); } }
EmailProcessor mantém a referência ao primeiro adicionado para ser chamado quando for interceptar algum email, assim passo por uma cadeia de interceptadores.
public class EmailProcessor { private EmailHandler successor; private EmailHandler first; public EmailProcessor(){ } public void addEmailHandler(EmailHandler emailHandler){ if(this.first == null){ this.first = emailHandler; }else{ this.successor.setNext(emailHandler); } this.successor = emailHandler; } public void handleRequest(Email email){ first.handleRequest(email); } }
Utilizando do EmailProcessor é enviado um email para tratamento. Dois handlers são adicionados, na forma de interceptar emails Gmail e Hotmail.
public class EmailClient { public static void main(String... args){ EmailProcessor emailProcessor = new EmailProcessor(); emailProcessor.addEmailHandler(new GmailHandler()); emailProcessor.addEmailHandler(new HotmailHandler()); Email email = new Email(); email.setFrom("diegogusava@gmail.com"); emailProcessor.handleRequest(email); } }Imprime: Email Gmail = diegogusava@gmail.com
Bibliografia:
1 - http://refcardz.dzone.com/refcardz/design-patterns
2 - http://java.dzone.com/articles/design-patterns-uncovered-chain-of-responsibility
3 - http://www.k19.com.br/downloads/apostilas-java/k19-k51-design-patterns-em-java
4 - http://www.slideshare.net/vsenger/33-design-patterns-com-java/download
Nenhum comentário:
Postar um comentário