Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Implementação mais abstrata

Pessoal implementei de uma forma mais abstrata e gostaria que vcs opinassem.

package br.com.schimidtsolutions.estudo.impostos;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;

import br.com.schimidtsolutions.estudo.investimento.ContaBancaria;

public abstract class Filtro {
    private Filtro outroFiltro;

    public Filtro() {}

    public Filtro(Filtro outroFiltro) {
        Objects.requireNonNull(outroFiltro);
        this.outroFiltro = outroFiltro;
    }

    public final List<ContaBancaria> filtrar(final List<ContaBancaria> listaContasOriginal) {
        Objects.requireNonNull(listaContasOriginal);

        Set<ContaBancaria> contasFiltradas = listaContasOriginal.stream()
                .filter(c -> isContaSelecionadaPeloFiltro(c))
                .collect(Collectors.toSet());

        unificarContasJaFiltradasComAsDeOutroFiltro(contasFiltradas, listaContasOriginal);

        return Lists.newArrayList(contasFiltradas);
    }

    private void unificarContasJaFiltradasComAsDeOutroFiltro(final Set<ContaBancaria> contasJaFiltradas, final List<ContaBancaria> listaContasOriginal) {

        if (outroFiltro != null) {
            List<ContaBancaria> contasFiltradasPorOutroFiltro = outroFiltro.filtrar(listaContasOriginal);

            if (contasFiltradasPorOutroFiltro != null && !contasFiltradasPorOutroFiltro.isEmpty()) {
                contasJaFiltradas.addAll(contasFiltradasPorOutroFiltro);
            }
        }
    }

    abstract boolean isContaSelecionadaPeloFiltro(ContaBancaria contaBancaria);
}

package br.com.schimidtsolutions.estudo.impostos;

import java.time.YearMonth;

import br.com.schimidtsolutions.estudo.investimento.ContaBancaria;

public class FiltroDataAberturaMesCorrente extends Filtro {

    public FiltroDataAberturaMesCorrente() {}

    public FiltroDataAberturaMesCorrente(Filtro outroFiltro) {
        super(outroFiltro);
    }

    @Override
    boolean isContaSelecionadaPeloFiltro(final ContaBancaria contaBancaria) {
        return YearMonth.from(contaBancaria.getDataAbertura()).equals(YearMonth.now());
    }
}

package br.com.schimidtsolutions.estudo.impostos;

import br.com.schimidtsolutions.estudo.investimento.ContaBancaria;

public class FiltroMenorQue100Reais extends Filtro {

    public FiltroMenorQue100Reais() {}

    public FiltroMenorQue100Reais(Filtro outroFiltro) {
        super(outroFiltro);
    }

    @Override
    boolean isContaSelecionadaPeloFiltro(final ContaBancaria contaBancaria) {
        return contaBancaria.getSaldo() < 100;
    }
}

package br.com.schimidtsolutions.estudo.impostos;

import br.com.schimidtsolutions.estudo.investimento.ContaBancaria;

public class FiltroMaiorQue500MilReais extends Filtro {

    public FiltroMaiorQue500MilReais() {}

    public FiltroMaiorQue500MilReais(Filtro outroFiltro) {
        super(outroFiltro);
    }

    @Override
    boolean isContaSelecionadaPeloFiltro(final ContaBancaria contaBancaria) {
        return contaBancaria.getSaldo() > 500_000;
    }
}

package br.com.schimidtsolutions.estudo.impostos;

import java.time.LocalDate;
import java.util.List;

import com.google.common.collect.Lists;

import br.com.schimidtsolutions.estudo.investimento.ContaBancaria;

public class SelecionadorContasASeremAnalisadas {

    public static void main(final String[] args) {
        Filtro filtroConjunto = new FiltroMenorQue100Reais(new FiltroMaiorQue500MilReais(new FiltroDataAberturaMesCorrente()));

        ContaBancaria contaBancaria1 = new ContaBancaria("Fulano", 99);
        ContaBancaria contaBancaria2 = new ContaBancaria("Ciclano", 500_001);
        ContaBancaria contaBancaria3 = new ContaBancaria("Beltrano", 150);
        ContaBancaria contaBancaria4 = new ContaBancaria("Dênis Schimidt", 99_000, LocalDate.now().minusMonths(2));

        List<ContaBancaria> contas = Lists.newArrayList(contaBancaria1, contaBancaria2, contaBancaria3, contaBancaria4);

        filtroConjunto.filtrar(contas)
            .forEach(System.out::println);
    }
}
1 resposta
solução!

Oi Felipe, essa implementação que vc fez está mais para um template method, que, na minha opinião, é uma outra forma de atingir o mesmo resultado de um decorator.. Só que é baseado em interfaces e outro é baseado em classes abstratas... Eu prefiro sem essa classe abstrata, mas não posso negar que ela funciona :).