2
respostas

Exercício investimento do Padrão Strategy

Bom dia a todos.

Implementando o exercício 8 da aula 1 me deparei um uma situação que me deixou um pouco confuso.

Vamos lá ... Eu criei um enum para o "Tipo de Investidor" conforme segue.

package padrao_strategy.investimento;

public enum TipoDoInvestidor {
    CONSERVADOR,
    MODERADO,
    ARROJADO;    
}

Logo após criei a classe do Investidor que recebe no construtor o seu perfil e o saldo.

package padrao_strategy.investimento;

public class Investidor {

    private TipoDoInvestidor tipoInvestidor;
    private double saldo;

    public Investidor(TipoDoInvestidor tipoInvestidor, double saldo) {
        this.tipoInvestidor = tipoInvestidor;
        this.saldo = saldo;        
    }

    public void deposita(double lucro) {
        this.saldo += lucro;
    }

    public double getSaldo() {
        return saldo;
    }

    public TipoDoInvestidor getTipoInvestidor() {
        return tipoInvestidor;
    }

}

Após isso e analisando o exemplo da implementação do exercício do calculo do imposto implementei as seguintes classes:

1º Eu criei uma interface Investimento

package padrao_strategy.investimento;

public interface Investimento {

    double calcula(Investidor investidor);

}

Logo após fui implementando as classes dos cálculos para os perfis CONSERVADOR, MODERADO e ARROJADO, conforme segue.

package padrao_strategy.investimento;

public class Conservador implements Investimento {

    public static final double RENTABILIDADE = 0.008;

    @Override
    public double calcula(Investidor investidor) {
        return investidor.getSaldo() * RENTABILIDADE;
    }

}
package padrao_strategy.investimento;

import java.util.Random;

public class Moderado implements Investimento {

    public static final double RENTABILIDADE_MINIMA = 0.007;
    public static final double RENTABILIDADE_MAXIMA = 0.025;

    @Override
    public double calcula(Investidor investidor) {
        boolean escolhido = new Random().nextDouble() < 0.5;

        if( escolhido ) {
            return investidor.getSaldo() * RENTABILIDADE_MAXIMA;            
        } else {
            return investidor.getSaldo() * RENTABILIDADE_MINIMA;
        }
    }

}
package padrao_strategy.investimento;

import java.util.Random;

public class Arrojado implements Investimento {

    public static final double RENTABILIDADE_MINIMA = 0.006;
    public static final double RENTABILIDADE_MEDIA  = 0.03;
    public static final double RENTABILIDADE_MAXIMA = 0.05;

    @Override
    public double calcula(Investidor investidor ) {
        double chance = new Random().nextDouble();;

        if( chance <= 0.2 )
            return investidor.getSaldo() * RENTABILIDADE_MAXIMA;
        else if (chance <= 0.3 )
            return investidor.getSaldo() * RENTABILIDADE_MEDIA;
        else 
            return investidor.getSaldo() * RENTABILIDADE_MINIMA;
    }

}

Até ai tudo bem e parece bastante com a resolução do professor. Porém minha dúvida é a seguinte: Na minha classe Investidor ela recebe no construtor um enum com o perfil (CONSERVADOR, MODERADO, ARROJADO) ...

A classe RealizadorDeInvestimentos ficou assim:

package padrao_strategy.investimento;

public class RealizadorDeInvestimento {

    public void investir(Investidor investidor, Investimento investimento) {

        double resultado = investimento.calcula(investidor);

        System.out.println("O saldo atual do investidor é: " + investidor.getSaldo());
        investidor.deposita(resultado * 0.75);
        System.out.println("O saldo atualizado do investidor é:" + investidor.getSaldo());
    }
}

E a classe Main ficou assim:

package padrao_strategy.investimento;

public class TesteDeInvestimento {

    public static void main(String[] args) {
        Investidor joao = new Investidor(TipoDoInvestidor.CONSERVADOR, 3500.0);
        Investimento investimento;

        if(joao.getTipoInvestidor() == TipoDoInvestidor.CONSERVADOR) {
            investimento = new Conservador();
        } else if ( joao.getTipoInvestidor() == TipoDoInvestidor.MODERADO ) {
            investimento = new Moderado(); 
        } else {
            investimento = new Arrojado();
        }

        RealizadorDeInvestimento realizadorDeInvestimento = new RealizadorDeInvestimento();
        realizadorDeInvestimento.investir(joao, investimento );

    }    
}

Na classe de teste eu tenho que verificar o tipo do Perfil para instanciar o investimento correspondente ao seu perfil. Tem alguma forma de evitar utilizar os IFs para criar o investimento correto? Nesta aboragem eu quebrei o princípio da padrão Strategy?

Desde já agradeço.

2 respostas

Olá!

Você pode colocar atributos na Enum, evitando os if's.

Exemplo:

public enum TipoDoInvestidor {
    CONSERVADOR(new Conservador()),
    MODERADO(new Moderado()),
    ARROJADO(new Arrojado());    

    private Investimento investimento;

    public TipoDoInvestidor (Investimento investimento) {
      this.investimento = investimento;
    }

    public Investimento getInvestimento() {
      return this.investimento;
    }

}

Oi rhelcris você criou tipoDeInvestimento e TipodeInvestidor um como constantes enum e outros como estratégias concretas, eu acredito que o padrão strategy ficou prejudicado com esse enum, você poderia encapsular todas as regras de uma estratégia na propria estrategia, que por serem classes concretas para cada estratégia não tem necessidade de ter um enum, cada membro dessa família de algoritmos saberia o seu tipo de investimento e inclusive você poderia mudar em tempo de execução de estratégia se fosse necessário.

Espero ter ajudado e bons estudos.