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

Dúvida sobre classe Avaliador

Fazendo os testes notei que essa classe Avaliador apenas usa dados que está contida no Leilão para chegar ao maiorValor , menorValor de lance de um dado leilao, etc. Pensando em OO não faria sentido matar essa classe Avaliador e deixar essas operaçoes para a classe Leilao?

3 respostas

Oi Felipe, tudo bem? Levando em consideração o conceito do mundo real, isso fugiria um pouco do cenário real, por que há o avaliador e ele não controla apenas o menor e maior valor. Porém, considerando o conceito do tell don't ask, sim, faz muito sentido essa sua sugestão. É uma melhoria que você pode fazer utilizando este conceito.

Contudo, evoluindo a idéia, você ainda vai precisar de um avaliador, por que ele faz o registro de quem fez o lance, entre outras coisas. Isso fará com que a classe avaliador fique mais sucinta, mas acho que não mata a classe totalmente. Entende?

Espero ter ajudado, bons estudos!

Uma coisa que já li é que devemos representar coisas do mundo real que fazem sentido no nosso contexto e nem tudo precisa ser representado.

Talvez o correto seria um Leilao ter um Avaliador e dentro dele estar a lista de lances recebidos com as operaçoes de max, minino, etc. Aí ele registraria lances tbm... :)

Se fosse adicionado mais features que dizem respeito ao Avaliador aí sim faria sentido representá-lo no modelo, mas do jeito que está no momento é apenas uma classe que serve para tirar estatísticas do leilão que possui a lista de lances.

package br.com.caelum.leilao.servico;

import java.util.Collections;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Objects;

import com.google.common.collect.Lists;

import br.com.caelum.leilao.dominio.Lance;
import br.com.caelum.leilao.dominio.Leilao;

public class Avaliador {
    private double maiorLance;
    private double menorLance;
    private double lanceMedio;
    private Leilao leilao;

    public void avaliar(Leilao leilao){
        Objects.requireNonNull(leilao);

        if(!leilao.getLances().isEmpty()){
            this.leilao = leilao;
            DoubleSummaryStatistics summaryStatistics = leilao.getLances().stream()    
                    .mapToDouble(l->l.getValor())
                    .summaryStatistics();
            maiorLance = summaryStatistics.getMax();
            menorLance = summaryStatistics.getMin();
            lanceMedio = summaryStatistics.getAverage();
        }
    }

    public double getMaiorLance() {
        return maiorLance;
    }

    public double getMenorLance() {
        return menorLance;
    }

    public double getLanceMedio() {
        return lanceMedio;
    }

    public List<Lance> getTresMaioresLances() {
        if(leilao!=null){
            List<Lance> lances = Lists.newArrayList(leilao.getLances());
            int indiceMinimoTresMaioresLances = lances.size() - 3 >= 0 ? lances.size() - 3 : 0;  
            List<Lance> tresMaioresLances = lances.subList(indiceMinimoTresMaioresLances,lances.size());
            Collections.sort(tresMaioresLances, Comparator.comparingDouble(Lance::getValor).reversed());

            return tresMaioresLances;
        }

        return Lists.newArrayList();
    }
}

Ex de como poderia ser

package br.com.caelum.leilao.dominio;

import java.util.Collections;
import java.util.List;

import com.google.common.collect.Lists;

public class Leilao {
    private String descricao;
    private List<Lance> lances;

    public Leilao(String descricao) {
        this.descricao = descricao;
        this.lances = Lists.newArrayList();
    }

    public void propoe(Lance lance) {        
        lances.add(lance);

        Collections.sort(lances);
    }

    public String getDescricao() {
        return descricao;
    }

    public EstatisticasDoLeilao getEstatiscasDoLeilao() {
        return new EstatisticasDoLeilao(this);
    }

    public List<Lance> getLances() {
        return Collections.unmodifiableList(lances);
    }

    @Override
    public String toString() {
        return String.format("Leilao [descricao=%s, lances=%s]", descricao, lances);
    }
}

package br.com.caelum.leilao.dominio;

import java.util.Collections;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.List;
import java.util.Objects;

import com.google.common.collect.Lists;

public class EstatisticasDoLeilao {
    private double maiorLance;
    private double menorLance;
    private double lanceMedio;
    private List<Lance> tresMaioreslances; 

    public EstatisticasDoLeilao(Leilao leilao) {
        Objects.requireNonNull(leilao);

        gerarEstatisticas(leilao);
    }

    private void gerarEstatisticas(Leilao leilao) {

        if(!leilao.getLances().isEmpty()){
            DoubleSummaryStatistics summaryStatistics = leilao.getLances().stream()    
                    .mapToDouble(l->l.getValor())
                    .summaryStatistics();
            maiorLance = summaryStatistics.getMax();
            menorLance = summaryStatistics.getMin();
            lanceMedio = summaryStatistics.getAverage();

            definirTresMaioresLances(leilao);

        }else{
            this.tresMaioreslances = Lists.newArrayList();
        }
    }

    public double getMaiorLance() {
        return maiorLance;
    }

    public double getMenorLance() {
        return menorLance;
    }

    public double getLanceMedio() {
        return lanceMedio;
    }

    private void definirTresMaioresLances(Leilao leilao) {
        List<Lance> lances = Lists.newArrayList(leilao.getLances());
        int indiceMinimoTresMaioresLances = lances.size() - 3 >= 0 ? lances.size() - 3 : 0;  
        List<Lance> tresMaioresLances = lances.subList(indiceMinimoTresMaioresLances,lances.size());
        Collections.sort(tresMaioresLances, Comparator.comparingDouble(Lance::getValor).reversed());

        this.tresMaioreslances = tresMaioresLances;
    }

    public List<Lance> getTresMaioreslances() {
        return tresMaioreslances;
    }
}
solução!

Verdade, porém, nestes assuntos conceituais, a discussão sobre certo e errado em fazer alguma coisa pode se tornar simplesmente subjetivo, onde a visão sobre o problema dentro do contexto pode variar de pessoa para pessoa.

Lembre-se, na grande maioria dos casos, não se trata de certo e errado, mas sim da melhor solução. Onde melhor solução também é variável, pode ser definida por simplicidade, performance ou outro indicador.

No mínimo devo parabeniza-lo por ter aberto essa discussão. Bons estudos!