Você está na página 1de 3

Chain of responsibility - Padro comportamental

Propsito:
Evitar acoplar o enviador da requisio com o recebedor (objeto que ir tratar a requisio) , dando
a oportunidade de mais de um objeto tratar esta requisio. Encadeie os recebedores e passe a
requisio por essa cadeia at que algum recebedor trate.
Quando utilizar?
Quando voc deseja que a requisio seja interceptada e tratada por mais de um objeto, e estes
objetos sejam escolhidos em tempo de execuo.
Consequncias:
- Reduz acoplamento: No acopla o enviador com o recebedor. O recebedor no sabe da existncia
de outros recebedores.
- Adiciona flexibilidade: Pode-se adicionar recebedores e retirar recebedores em tmepo de
execuo.
- No h garantia que algum recebedor intercepte algum objeto.
Exemplo:
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 ia 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 mtodos que as classes concretas devero implementar. No
caso o mtodo setNext, indica a prxima classe que dever tratar a requisio, 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 mtodo handleRequest ir


verificar se o email do tipo que deve ser interceptado, caso for, o mtodo doHandle far o
tratamento, caso no for, passa para o prximo objeto da cadeia se existir, caso no exista a
interceptao acaba. Cuidado que seu objeto no final pode no 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 mantm a referncia 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 so 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);
}
}