Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Formato diferente de cálculo

Poderia fazer dessa forma:

    public abstract class Filtro
    {
        public abstract IList<Conta> Filtra(IList<Conta> contas);

        private readonly Filtro OutroFiltro;

        //-- Construtor com novo imposto
        public Filtro(Filtro OutroFiltro)
        {
            this.OutroFiltro = OutroFiltro;
        }

        //-- Construtor default
        public Filtro()
        {
            this.OutroFiltro = null;
        }

        public IList<Conta> AplicaFiltros(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();
            resultado = Filtra(contas);

            if (this.OutroFiltro != null)
            {
                resultado = OutroFiltro.Filtra(resultado);
            }

            return resultado;
        }
    }

    public class SaldoBaixo : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {
                if(item.Saldo < 100)
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }
    public class SaldoAlto : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {
                if (item.Saldo > 500000)
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }
    public class MesAtual : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {

                if (item.Data.Month.Equals( DateTime.Now.Month ) )
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }

Dessa forma não precisa replicar o outro Filtro em todos os métodos

5 respostas

Opa, é uma boa utilização das classes abstratas. Só identifiquei um problema: caso os filtros SaldoAlto e SaldoBaixo rodem em sequência, o resultado será sempre vazio.

Um exemplo do caso acima seria algo como

IList<Conta> contas = todasAsContas;
Filtro filtro = new SaldoBaixo(
                    new MesAtual(
                        new SaldoAlto()
                    )
                );
// lista sempre vazia
IList<Conta> contasFiltradas = filtro.Filtra(contas);

Isso aconteceria pois a intersecção entre os dois filtros é nula. Nem um item que tenha saldo baixo pode ter saldo alto. Portanto pode ser importante garantir de algum modo que um não será executado após o outro.

Marco, caso sejam aplicados filtros e o resultado final for vazio, acredito que possa "resolver" com a seguinte alteração:

if (todasAsContas.Count > 0 && contasFiltradas.Count == 0){
//-- Avisar ao usuário que os filtros aplicados não retornam nenhuma conta válida 
}

É uma alternativa válida, sim!

Bom, esse tópico não representava bem uma dúvida, então não sei se tem uma "solução". O que você acha? Marque algum comentário como solução pra deixar o tópico resolvido ;)

solução

O resultado ficaria então:

    public abstract class Filtro
    {
        public abstract IList<Conta> Filtra(IList<Conta> contas);

        private readonly Filtro OutroFiltro;

        //-- Construtor com novo imposto
        public Filtro(Filtro OutroFiltro)
        {
            this.OutroFiltro = OutroFiltro;
        }

        //-- Construtor default
        public Filtro()
        {
            this.OutroFiltro = null;
        }

        public IList<Conta> AplicaFiltros(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();
            resultado = Filtra(contas);

            if (this.OutroFiltro != null)
            {
                resultado = OutroFiltro.Filtra(resultado);
            }

            return resultado;
        }
    }

    public class SaldoBaixo : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {
                if(item.Saldo < 100)
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }
    public class SaldoAlto : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {
                if (item.Saldo > 500000)
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }
    public class MesAtual : Filtro
    {
        public override IList<Conta> Filtra(IList<Conta> contas)
        {
            IList<Conta> resultado = new List<Conta>();

            foreach (Conta item in contas)
            {

                if (item.Data.Month.Equals( DateTime.Now.Month ) && item.Data.Year.Equals( DateTime.Now.Year ) )
                {
                    resultado.Add(item);
                }
            }

            return resultado;
        }
    }

Ao aplicar os filtros, pode verificar se o resultado ficou vazio da seguinte forma:

if (todasAsContas.Count > 0 && contasFiltradas.Count == 0){
//-- Avisar ao usuário que os filtros aplicados não retornam nenhuma conta válida 
}

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