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

Dúvida com Strategy

Em diversos códigos que vi por ai sobre o padrão strategy, é utilizado um Enum que funciona como se fosse a condição para aplicar uma estratégia ou outra. No exemplo abaixo temos uma implementação de strategy, no caso vai ser aplicado uma determinada estratégia para validar um funcionário de acordo com o TipoFuncionário(Enum). No entanto na vida real é mais natural que o TipoFuncionario, Cargo,etc... na realidade estejam salvas em um banco de dados e TipoFuncionario seja uma entidade JPA e não um enum. Como aplicar esse padrão substituindo a Enumeration por uma entidade JPA? ou elas como elas podem trabalhar juntas?

public interface FuncionarioValidator {
    void validate(Funcionario f) throws Exception;
}
public class CeletistaValidator implements FuncionarioValidator {

    @Override
    public void validate(Funcionario f) throws Exception {
        System.out.println(f.getNome() + " -> " + getClass().getName());
    }

}

public class QuadroPermanenteValidator implements FuncionarioValidator {

    @Override
    public void validate(Funcionario f) throws Exception {
        System.out.println(f.getNome() + " -> " + getClass().getName());
    }

}

public class SurfistaValidator implements FuncionarioValidator {

    @Override
    public void validate(Funcionario f) throws Exception {
        System.out.println(f.getNome() + " -> " + getClass().getName());
    }

}
public enum TipoFuncionario {

    Celetista(new CeletistaValidator()), 
    QuadroPermanente(new QuadroPermanenteValidator()), 
    Surfista(new SurfistaValidator());

    private FuncionarioValidator validator;

    private TipoFuncionario(FuncionarioValidator validator) {
        this.validator = validator;
    }

    public FuncionarioValidator getValidator() {
        return validator;
    }

}
public class Funcionario {

    private Integer id;
    private String nome;
    private TipoFuncionario tipo;

    public Funcionario(Integer id, String nome, TipoFuncionario tipo) {
        this.id = id;
        this.nome = nome;
        this.tipo = tipo;
    }

    public Integer getId() {
        return id;
    }

    public String getNome() {
        return nome;
    }

    public TipoFuncionario getTipo() {
        return tipo;
    }

}
public class FuncionarioTest {

    @Test
    public void test() throws Exception {

        //cria lista de funcionários
        List<Funcionario> funcionarios = new ArrayList<Funcionario>();
        funcionarios.add(new Funcionario(1, "João", TipoFuncionario.Celetista));
        funcionarios.add(new Funcionario(2, "José", TipoFuncionario.QuadroPermanente));
        funcionarios.add(new Funcionario(3, "Maria", TipoFuncionario.Surfista));

        //valida todos
        for (Funcionario funcionario : funcionarios) {
            funcionario.getTipo().getValidator().validate(funcionario);
        }

    }

}
5 respostas

Oi Ricardo!

Mesmo que seu TipoFuncionario seja uma entidade no banco de dados, ele pode ter um atributo com o enum, dizendo qual o tipo dele, faz sentido?

Aí a implementação com a entidade ou direto com o enum não muda muito.

Se ficou alguma dúvida me avise que eu tento explicar melhor!

abraços!

Olá Philippe, na realidade não compreendi muito bem, como vou representar minha entidade como um enum?

solução!

Oi Ricardo! Você não vai representar sua entidade com um enum, a sua entidade terá um enum como atributo, por exemplo:

@Entity
class Funcionario {

    private Long id;

    @OneToOne
    private EntidadeTipoFuncionario entidadeTipo;

    // outros atributos

   public TipoDeFuncionario getTipo() {
    return tipo.getTipo();
   }
}
@Entity
class EntidadeTipoFuncionario {

    private Long id;

    @Enumerated
    private TipoDeFuncionario enumTipo; //esse é o seu enum mesmo

    private BigDecimal salario;

    // outros atributos

   public TipoDeFuncionario getTipo() {
    return enumTipo;
   }
}

Acho que entendi, funciona para coisas mais simples ou para tabelas que possuem valores que não mudam ou que mudam com pouquíssima frequência, como por exemplo forma de pagamento ou dependendo do cenário funcione para o TipoFuncionário também, então se minha tabela tipo_funcionário tem a coluna nome, bastaria eu mapear esse atributo com a enumeration, bem legal.

Mas para classes como Cargo por exemplo fica complicado fazer com enum, pois cargos são criados e extintos o tempo todo, e a cada cargo criado ou removido teriamos que fazer manutenção na enum, correto?

Sim, infelizmente com tabelas de mudanças frequentes, se forem criados valores novos, ou deletados valores antigos, seria necessário criar estratégias novas ou deletar estratégias antigas.