DEV Community

Hernani Almeida
Hernani Almeida

Posted on

O Poder da Classe Enum com métodos abstratos

Ferramentas necessárias:

Bora galera para mais um post onde vou detalhar uma forma de utilizar a classe Enum para deixar seu código mais limpo e mais fácil de entender.
Vamos criar uma aplicação Springboot que ira cadastrar colaboradores de uma empresa (nome, cargo, bonificação), vamos utilizar o poder da classe Enum e dos métodos abstratos para gerar o salario do colaborador mais a bonificação do colaborador conforme o seu cargo.
Para iniciarmos crie seu projeto Spring através do site Spring Initializr conforme imagem abaixo
Image description
Vamos configurar nosso banco de dados H2, em application.properties coloque as seguintes configurações.

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
Enter fullscreen mode Exit fullscreen mode

Nesse artigo o foco e mostrar como podemos utilizar a classe Enum com métodos abstratos para atingir uma regra de negocio e manter um código limpo, portanto não iremos nos preocupar com design patterns ou estrutura de códigos blz.
Dito isso criamos nossa classe Colaborador que será nossa Entity e a classe Enum TipoCargo.
Colaborador

package com.example.demo;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Positive;

@Entity
public class Colaborador {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    private String nome;

    @NotBlank
    private TipoCargo cargo;

    @NotBlank
    @Positive
    private Double salario;

    @Deprecated
    public Colaborador() {
    }

    public Long getId() {
        return id;
    }

    public String getNome() {
        return nome;
    }

    public TipoCargo getCargo() {
        return cargo;
    }

    public Double getSalario() {
        return salario;
    }

    public Colaborador(String nome, TipoCargo cargo, Double salario) {
        this.nome = nome;
        this.cargo = cargo;
        this.salario = salario + cargo.bonificacaoColaborador(salario);
    }

    @Override
    public String toString() {
        return "Colaborador{" +
                "id=" + id +
                ", nome='" + nome + '\'' +
                ", cargo=" + cargo +
                ", salario=" + salario +
                '}';
    }
}
Enter fullscreen mode Exit fullscreen mode

TipoCargo

package com.example.demo;

public enum TipoCargo {
    GERENTE{
        @Override
        public double bonificacaoColaborador(Double salario) {
            return salario * 0.1;
        }
    },
    SUPERVISOR{
        @Override
        public double bonificacaoColaborador(Double salario) {
            return salario * 0.20;
        }
    },
    AJUDANTE{
        @Override
        public double bonificacaoColaborador(Double salario) {
            return salario * 0.50;
        }
    },
    DEV{
        @Override
        public double bonificacaoColaborador(Double salario) {
            return salario * 0.70;
        }
    };

/* metodo abstrato recebe o salario do colaborador parametro*/
    public abstract double bonificacaoColaborador(Double salario);
}
Enter fullscreen mode Exit fullscreen mode

E aqui que a magica acontece, veja que em nossa classe Enum TipoCargo criamos um método abstrato bonificacaoColaborador que será por obrigação implementado por cada enum de nossa classe.
Este método recebe o salario do colaborador como parâmetro e retorna a porcentagem desse salario conforme o cargo especificado no enum.
Já na classe Colaborador quando passamos os valores para criar um novo colaborador, através do constructor, o salario e calculado utilizando o enum passado no corpo da requisição para chamar o método bonificacaoColaborador que será implementado conforme o valor desse enum.
Vamos criar agora as classes, ColaboradorRepositoy, ColaboradorController e ColaboradorForm para testarmos nossa aplicação via Postman.
ColaboradorRepository

package com.example.demo;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ColaboradorRepository extends JpaRepository<Colaborador,Long> {
}
Enter fullscreen mode Exit fullscreen mode

ColaboradorController

package com.example.demo;

import org.springframework.http.HttpEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class ColaboradorController {

    private ColaboradorRepository colaboradorRepository;

    public ColaboradorController(ColaboradorRepository colaboradorRepository) {
        this.colaboradorRepository = colaboradorRepository;
    }


    @PostMapping("/colaborador")
    @Transactional
    public String create(@RequestBody ColaboradorForm colaboradorForm){
        Colaborador colaborador = colaboradorForm.converte();
        colaboradorRepository.save(colaborador);
        return colaborador.toString();
    }

    @GetMapping("/colaborador")
    public List<Colaborador> findAll(){
        return colaboradorRepository.findAll();
    }
}
Enter fullscreen mode Exit fullscreen mode

ColaboradorForm

package com.example.demo;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Positive;

public class ColaboradorForm {

    @NotBlank
    private String nome;

    @NotBlank
    private TipoCargo cargo;

    @NotBlank
    @Positive
    private Double salario;

    public ColaboradorForm(String nome, TipoCargo cargo, Double salario) {
        this.nome = nome;
        this.cargo = cargo;
        this.salario = salario;
    }

    public Colaborador converte() {
        return new Colaborador(nome, cargo, salario);
    }
}
Enter fullscreen mode Exit fullscreen mode

Podemos então cadastrar um colaborador via Postman e ver o funcionamento da nossa estratégia em utilizar o Enum.
Image description
Colaborador cadastrado com sucesso, e veja que passamos no corpo da requisição o salario de R$ 1000.00 mas o colaborador foi salvo no banco de dados com o salario no valor de R$1500.00
Image description
Isso porque o cargo do colaborador passado na requisição e referente ao enum no valor de AJUDANTE e este enum utiliza o método bonificacaoColaborador que acrescenta 50% a mais do valor do salario do colaborador.
Veja o que acontece se cadastrarmos este mesmo valor mas com o cargo de GERENTE.
Image description
Teve um aumento de apenas 10% conforme especificamos no enum de valor GERENTE.
A vantagem de usarmos este tipo de abordagem e que se precisarmos acrescentar novos cargos e bonificações só será necessário acrescentar valores na classe Enum TipoCargo e implementar o método bonificacaoColaborador com a regra de negocio especifica daquele cargo.
Feito galera obrigado por ler ate aqui e ate a próxima, deixo meus contatos aqui para quem quiser me adicionar.

linkedin
github

Latest comments (0)