Logo

dev-resources.site

for different kinds of informations.

O Poder da Classe Enum com métodos abstratos

Published at
3/30/2022
Categories
java
cleancode
springboot
enum
Author
2020nani
Categories
4 categories in total
java
open
cleancode
open
springboot
open
enum
open
Author
8 person written this
2020nani
open
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

enum Article's
30 articles in total
Favicon
Mastering ENUMs in Go
Favicon
The 3 kinds of Enum in Rails
Favicon
Enhancing Enum Constants in Laravel with Description and Label Attributes
Favicon
Should I stay or should I go? Enums in TypeScript - error case study
Favicon
Effective Enum
Favicon
Result in Rust: another way of error handling
Favicon
How to convert a TypeScript built-in enum to a GraphQL enum
Favicon
Leveraging Enums in Angular: Enhancing Code Clarity and Reliability
Favicon
Typescript enum vs. "as const"
Favicon
Enum Fábrica Solitão em Java
Favicon
Implementing Enums in Golang
Favicon
Elixirでリストの最初の要素を取得
Favicon
[JS TS] How to create an object with keys based on enum
Favicon
Enum ou Enumerations no PHP
Favicon
Replacing If-Else Statements with Enums in Java
Favicon
Dart enhanced enum with custom values
Favicon
Working with Enums in Rust
Favicon
Modelando algoritmos complexos com enum
Favicon
Managing Task Status Transitions in TypeScript with Enums and Object Mapping
Favicon
TypeScript Enum's vs Discriminated Unions
Favicon
Strategy Pattern no Spring Boot Usando Enum
Favicon
Problem in C Pointer
Favicon
Merge TypeScript Enums
Favicon
Agora sim, o grande ganho do enum no Dart 2.17
Favicon
How to proper use ambient enum from Definition file
Favicon
O Poder da Classe Enum com métodos abstratos
Favicon
Refactoring code with the Strate Pattern
Favicon
🔥Input Enums for a better Development Experience 🔥 😋✂️
Favicon
O pequeno grande ganho do enum no Dart 2.15
Favicon
Typescript enums drawbacks and solutions

Featured ones: