Chain of Responsability

Intenção

Evita o acoplamento do remetente de uma solicitação ao seu receptor, ao dar a mais de um objeto a oportunidade de tratar a solicitação. Encadear os objetos receptores, passando a solicitação ao longo da cadeia até que um objeto a trate.

Vantagens

Desvantagens

Exemplos

Exemplo #1

Uma Entidade de Pagamento, por exemplo uma casa loterica, efetua pagamentos de boletos dos bancos A e B e seu sistema possui um módulo para efetuar o pagamento de cada um deles. Como para cada banco o registro de pagamento é realizado de forma diferente, o uso do padrao Chain of Responsability permite que seja criado uma cadeia em que cada membro tem o papel de registrar o pagamento de um boleto de um banco especifico, ou seja no exemplo supracitada a cadeia é formada por dois membros: um para registrar os pagamentos dos boletos do banco A e outro para os boletos do banco B. O membro do tipo PaymentBankA registra pagamentos de boletos do Banco A e do tipo PaymentBankB registra pagamentos do Banco B. 

Diagrama de Classe

Exemplo #1 - Diagrama

Participantes

  • Handler(PaymentBankChain): Define uma interface para tratar solicitações; (opcional) implementa o elo (link) ao sucessor.
  • ConcreteHandler(PaymentBankA, PaymentBankB): trata de solicitações pelas quais é reponsável; pode acessar seu sucessor.
  • Client(PaymentEntity): inicia a solicitação para um objeto ConcreteHandler da cadeia.

Código

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public class BankSlip {

    protected int code;
    protected String shopName;
    protected double value;
    protected int bankCode;
    protected String status;

    public BankSlip(int code, String shopName, int bankCode, double value, String status) {
        this.code = code;
        this.shopName = shopName;
        this.bankCode = bankCode;
        this.value = value;
        this.status = status;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public void setshopName(String shopName) {
        this.shopName = shopName;
    }

    public void setbankCode(int bankCode) {
        this.bankCode = bankCode;
    }

    public void setValue(double value) {
        this.value = value;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public int getCode() {
        return code;
    }

    public String getshopName() {
        return shopName;
    }

    public int getbankCode() {
        return bankCode;
    }

    public double getValue() {
        return value;
    }

    public String getStatus() {
        return status;
    }
}
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public class Client {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
    
     PaymentBankChain banks;
     banks = new PaymentBankA();
     banks.setNext(new PaymentBankB());
        
   
    BankSlip bankslip1 = new BankSlip(2520,"Casas Bahia", 1, 1000,"not paid"); 
    BankSlip bankslip2 = new BankSlip(3250,"Eletrocenter", 2, 2000,"not paid"); 
    
 
    PaymentEntity pe1 = new PaymentEntity("Loteria Cavaleiros", "lottery");
    pe1.makePayment(bankslip1,banks);
    pe1.makePayment(bankslip2,banks);
   
    
    
    }
    
}
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public class PaymentBankA implements PaymentBankChain {
 
    protected PaymentBankChain next;
    double value;
      
    @Override
    public void setNext(PaymentBankChain next) {
        this.next = next;
    }

    @Override
    public void registerPayment(BankSlip bankSlip){
            
          if(bankSlip.getbankCode()==1){
           value = bankSlip.getValue() - bankSlip.getValue() * 0.02;   
           bankSlip.setValue(value);
           bankSlip.setStatus("Paid");
            System.out.println("Bank slip of bank A:\nBank Slip:"+ bankSlip.getCode() +"\nShop:"+ bankSlip.getshopName()+
                               "\nAmount Received:"+ bankSlip.getValue()+ "\nBank Code:"+ bankSlip.getbankCode() +"\nStatus Current:"+ bankSlip.getStatus());
           System.out.println("========================");
          }else
              this.next.registerPayment(bankSlip);
          
    }
}
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public class PaymentBankB implements PaymentBankChain { 
     
    protected PaymentBankChain next;
    double value;
      
    @Override
    public void setNext(PaymentBankChain nextforma) {
        this.next = nextforma;
    }

    @Override
    public void registerPayment(BankSlip bankSlip){
          
        if(bankSlip.getbankCode()==2){  
           value = bankSlip.getValue() - bankSlip.getValue() * 0.03;   
           bankSlip.setValue(value);
           bankSlip.setStatus("Paid");
            System.out.println("Bank slip of bank B:\nBank Slip:"+ bankSlip.getCode() +"\nShop:"+ bankSlip.getshopName()+
                               "\nAmount Received:"+ bankSlip.getValue()+ "\nBank Code:"+ bankSlip.getbankCode() +"\nStatus Current:"+ bankSlip.getStatus());
           System.out.println("========================");
      
      }
    }
}
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public interface PaymentBankChain {
    
    void setNext(PaymentBankChain next);
      
    void registerPayment(BankSlip next);
 

}
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ChainResponsabilityBRIOF;

/**
 *
 * @author patrickbelem
 */
public class PaymentEntity {

   protected String name;
     protected String type;

       
    public PaymentEntity(String name, String type) {
        this.name = name;
        this.type = type;
    }
    
    public void setType(String type) {
        this.type = type;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public String getType() {
        return type;
    }


    public void makePayment(BankSlip bankSlip, PaymentBankChain banks) throws Exception {
      
        banks.registerPayment(bankSlip); // Passa o bankSlip para a Cadeia
    
   
  }

}
Clique aqui para fazer o download do código completo de implementação deste Design Pattern.

Padrões Relacionados

Este Padrão pode ser usado para resolver os seguintes problemas: