Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

Dúvida: Ex.5 - Chain Of Responsability - Recebendo o próximo item da corrente pelo construtor

A parte de receber pelo construtor eu entendi. Pois dessa forma você força o desenvolvedor a não esquecer de determinar o próximo elemento a ser verificado pela corrente, onde usando o método "setProximo" ele pode acabar esquecendo de determinar.

O problema é que uma vez que determina-se o próximo item pelo construtor, como fica no método "main"? E na classe que especifica a sequencia da corrente? Visto que um dos métodos que recebe o próximo elemento pelo construtor será o primeiro da corrente, e o primeiro da corrente não irá ter elemento pra receber no construtor, já que ele é o que está começando a corrente.

Estou tendo problemas de NullPointer Exception já que vem nulo.

Como fica? Não estou conseguindo resolver!

5 respostas

Daniel, posta seu código para dar uma olhada.

Segue o fonte das classes. Vou mandar todos, desculpe se não tinha necessidade, mas preferi postar todos pra garantir que todas as informações necessárias estivessem aí.

Classe CONTA:

public class Conta {

    private String nome;
    private double saldo;

    public Conta( String nome, double saldo ) {

        this.nome = nome;
        this.saldo = saldo;

    }

    /**
     * @return the nome
     */
    public String getNome() {
        return nome;
    }

    /**
     * @return the saldo
     */
    public double getSaldo() {
        return saldo;
    }

}

Classe "FormatadorDeRequisicao", que é a classe onde contém a determinação da sequencia da corrente, e é onde gera o problema já que ao instanciar o objeto "formatoXML" não tem o que colocar no construtor, entrando "nulo". Da forma que está aqui nem compilar compilaria visto que dá erro por não ter nada no construtor:

public class FormatadorDeRequisicao {

    public String formatar( Formato formato, Conta conta ) {

        FormatoXML formatoXML = new FormatoXML();
        FormatoCSV formatoCSV = new FormatoCSV( formatoXML );
        FormatoPORCENTO formatoPorCentro = new FormatoPORCENTO( formatoCSV );

        return formatoXML.getRetorno( formato, conta );
    }

}

Enum contendo os valores para direcionar o tipo de retorno do aplicativo "Formato":

public enum Formato implements FormatoRequisicao {

    XML,
    CSV,
    PORCENTO;

    @Override
    public String getRetorno(Formato formato, Conta conta) {
        return "";
    }

}

Método que retorna o valor CSV "FormatoCSV": ``` public class FormatoCSV implements FormatoRequisicao {

private FormatoRequisicao requisicao;

public FormatoCSV( FormatoRequisicao requisicao ) { this.requisicao = requisicao; }

@Override public String getRetorno(Formato formato, Conta conta) { if( formato == Formato.CSV ) { return conta.getNome() + ";" + conta.getSaldo(); } else { return this.requisicao.getRetorno( formato, conta ); } }

}

Desconsidere a classe "FormatoCSV" anterior, sem querer postei sem estar pronto, considere daqui pra baixo a continuação das postagens das classes:

Classe "FormatoCSV":

public class FormatoCSV implements FormatoRequisicao {

    private FormatoRequisicao requisicao;

    public FormatoCSV( FormatoRequisicao requisicao ) {
        this.requisicao = requisicao;
    }

    @Override
    public String getRetorno(Formato formato, Conta conta) {
        if( formato == Formato.CSV ) {
            return conta.getNome() + ";" + conta.getSaldo();
        } else {
            return this.requisicao.getRetorno( formato, conta );
        }
    }

}

Formato que retorna os valores da conta entre "%" classe "FormatoPORCENTO":

public class FormatoPORCENTO implements FormatoRequisicao {

    private FormatoRequisicao requisicao;

    public FormatoPORCENTO( FormatoRequisicao requisicao ) {
        this.requisicao = requisicao;
    }

    @Override
    public String getRetorno(Formato formato, Conta conta) {
        return conta.getNome() + "%" + conta.getSaldo();
    }

}

Classe que retorna o valor "XML", classe "FormatoXML":

public class FormatoXML implements FormatoRequisicao {

    private FormatoRequisicao requisicao;

    public FormatoXML( FormatoRequisicao requisicao ) {
        this.requisicao = requisicao;
    }

    @Override
    public String getRetorno( Formato formato, Conta conta ) {
        if( formato == Formato.XML ) {
            return "XML";
        } else {
            return this.requisicao.getRetorno( formato, conta );
        }
    }

}

Interface "FormatoRequisicao":

public interface FormatoRequisicao {

    String getRetorno( Formato formato, Conta conta );

}

Classe contendo o método MAIN:

public class Main {

    public static void main(String[] args) {

        Conta conta = new Conta( "Daniel", 2890.45d );

        FormatadorDeRequisicao formatador = new FormatadorDeRequisicao();

        System.out.println( formatador.formatar(Formato.XML, conta) );
        System.out.println( formatador.formatar(Formato.CSV, conta) );
        System.out.println( formatador.formatar(Formato.PORCENTO, conta) );

    }

}
solução!

Para contornar o problema de null pointer, se é que eu entendi direito a sua dúvida, basta inverter a ordem em que os objetos são instanciados.

Algo tipo assim:

public class CalculadorDeProcessadorRequisicao {
    public String processarRequisicao(Requisicao requisicao, ContaBancaria conta) {
        // Tive que inverter a ordem de instaciação dos objs

        ProcessadorRequisicao pVazio = new ProcessadorRequisicaoVazio();
        ProcessadorRequisicao pPORCENTO = new ProcessadorRequisicaoPORCENTO(pVazio);
        ProcessadorRequisicao pCSV = new ProcessadorRequisicaoCSV(pPORCENTO);
        ProcessadorRequisicao pXML = new ProcessadorRequisicaoXML(pCSV);

        return pXML.processar(requisicao, conta);
    }
}

Fica um pouco confuso para quem vai dar manutenção, pois a ordem natural de formação da cadeia está ao contrário.

Show de bola Gustavo. Fui meio lerdo agora, esqueci do objeto da classe vazia que não retorna nada. Resolveu! Obrigadão!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software