Chain of Responsability

Solução Proposta

Desacopla o objeto emissor do objeto receptor pela passagem da solicitação por uma cadeia de receptores potenciais.

Vantagens

Desvantagens

Exemplo

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

Chain of Responsability - 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