Chain of Responsibility
Eduardo Motta
[email protected]
Propósito do Padrão


Evitar o acoplamento entre o remetente de
uma requisição aos seus receptores, dando
a chance de mais de um objeto tratar a
requisição
Encadear os objetos receptores e passar a
requisição ao longo da cadeia até que um
objeto a trate
Motivação (1)




Sistema de auxílio sensível ao contexto
O objeto que fornece a informação de auxílio não é
conhecido pelo que recebe a requisição (por
exemplo, um botão)
Uma cadeia de responsabilidade pode desacoplar
os requisitantes dos receptores. A requisição passa
através da cadeia até que um objeto a trate
Cada objeto na cadeia compartilha uma interface
comum para manipular as requisições e acessar seu
sucessor na cadeia
Motivação (2)
Aplicabilidade



Quando mais de um objeto pode tratar uma
requisição e quem efetivamente a trata não é
conhecido a priori
Para emitir requisições para um ou mais
objetos sem especificar o receptor
explicitamente
Quando o conjunto de objetos que pode
tratar a requisição deve ser especificado
dinamicamente
Estrutura
Participantes (1)

Handler
–
–

Define a interface para o tratamento das requisições
Implementa a ligação com o sucessor (opcional)
ConcreteHandler
–
–
–
Trata as requisições pelas quais ele é responsável
Pode acessar seu sucessor
Se o ConcreteHandler pode tratar a requisição, ele
o faz; se não, encaminha a requisição ao seu
sucessor
Participantes (2)

Client
–
Inicia a requisição a um objeto ConcreteHandler
da cadeia
Colaboração
Consequências
Benefícios
 Acoplamento reduzido
 Flexibilidade na atribuição de
responsabilidades aos objetos
Desvantagem
 Tratamento da requisição não é garantido
Exemplos (1)
import java.io.*;
abstract class PurchasePower {
protected final double base = 500;
protected PurchasePower successor;
public void setSuccessor(PurchasePower successor){
this.successor = successor;
}
class ManagerPPower extends PurchasePower {
private final double ALLOWABLE = 10 * base;
class DirectorPPower
extends
PurchasePower
{
abstract
public
void processRequest(PurchaseRequest
request);
private final
double
ALLOWABLE
=
20
*
base;
} processRequest(PurchaseRequest
publicVicePresidentPPower
void
request
class
extends PurchasePower
{ ) {
if(
request.getAmount()
<
ALLOWABLE
)
private final double ALLOWABLE = 40 * base;
public
void
processRequest(PurchaseRequest
request ) {
classSystem.out.println("Manager
PresidentPPower
extends PurchasePower
will approve{ $"+ request.getAmount());
if( request.getAmount()
< ALLOWABLE
) * base;
double ALLOWABLE
= 60
elseprivate
public
void final
processRequest(PurchaseRequest
request) {
System.out.println("Director will approve $"+ request.getAmount());
if(
successor
!=
null)
if( request.getAmount() < ALLOWABLE )
else
public
void processRequest(PurchaseRequest
successor.processRequest(request);
System.out.println("Vice
President willrequest){
approve $" +
if( if(
successor
!=
null)
request.getAmount() < ALLOWABLE )
} request.getAmount());
successor.processRequest(request);
System.out.println("President will approve $" + request.getAmount());
}
else
}
if( else
successor != null )
}
System.out.println( "Your request for $" + request.getAmount() + " needs
successor.processRequest(request);
} a board meeting!");
}
}
}
Exemplos (2)
class PurchaseRequest {
private int number;
private double amount;
private String purpose;
public PurchaseRequest(int number, double amount, String purpose){
this.number = number;
this.amount = amount;
this.purpose = purpose;
}
public double getAmount() {
return amount;
}
public void setAmount(double amt){
amount = amt;
}
public String getPurpose() {
return purpose;
}
public void setPurpose(String reason) {
purpose = reason;
Exemplos (3)
class CheckAuthority {
public static void main(String[] args){
ManagerPPower manager = new ManagerPPower();
DirectorPPower director = new DirectorPPower();
VicePresidentPPower vp = new VicePresidentPPower();
PresidentPPower president = new PresidentPPower();
manager.setSuccessor(director);
director.setSuccessor(vp);
vp.setSuccessor(president);
try{
while (true) {
System.out.println("Enter the amount to check who should approve
your expenditure.");
System.out.print(">");
double d = Double.parseDouble(new BufferedReader(new
InputStreamReader(System.in)).readLine());
manager.processRequest(new PurchaseRequest(0, d, "General"));
}
}catch(Exception e){
System.exit(1);
}
}
}
Dúvidas? Perguntas?
Eduardo Motta
[email protected]
Download

Slides - (LES) da PUC-Rio