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

[Dúvida] Preciso de sugestões de melhoria de código em Java seguindo boas práticas e Clean Code

Sugestões de melhoria de código em Java seguindo boas práticas e Clean Code

Como aplicar Clean Code se nunca li o livro?

Atualmente, estou aprendendo a utilizar o framework Spring trabalhando no projeto ScreenMatch, e minha questão principal é que estou tentando aplicar alguns conceitos de clean code, mas não sei exatamente se estou fazendo isso adequadamente, até porque nunca li o livro.


Código da minha classe de "Interface de Usuário":

Compartilho parte do código aqui (principalmente o da minha classe de interface de usuário) pra saber se estou fazendo isso adequadamente na minha aplicação, e o que posso fazer (e talvez o que seja mais importante de se prestar atenção) pra conseguir escrever código limpo com boas práticas. (Código completo aqui: ScreenMatch-Without-Web)

// Método principal que "junta tudo" pra ser chamado no método main de maneira mais legível Insira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidadeInsira aqui a descrição dessa imagem para ajudar na acessibilidade

Conclusão

// Tentei colocar nomes descritivos para variáveis e funções na aplicação Estou completamente aberto a críticas (construtivas) e sugestões pra melhorar esse código e até de uma maneira mais ampla. Obrigado por ler até aqui!

2 respostas
solução!

O tema de clean code ou boas praticas chega a ser um pouco quanto pessoal e cada um pode defender seus proprios principios, porem em relacao ao seu codigo tem algumas coisas que poderia melhorar.

UserInterface

  • O nome eh um pouco contraditorio pois eh uma classe concreta e pode dar a entender que eh na verdade uma interface.
  • Todos os metodos sao estaticos, se eh algo que deve ser executado na main faria sentido tirar o static dos metodos e instanciar na classe onde ela eh chamada.
  • A classe de "Interface de usuarios" trata muito mais coisas do que apenas o que sera disponibilizado ao usuario, particularmente nao vi seu codigo inteiro mas seria interessante abstrair parte do codigo que trata sobre logica das series para outra classe. (Single Responsability Principle)
  • getEpisodesFromEpisodesData(List) & getEpisodesFromEpisodesData(Object), voce tem dois metodos que fazem coisas diferentes com o mesmo nome, alem disso o metodo que recebe apenas um objeto poderia ser chamado dentro do metodo que recebe uma lista.

Sobre a questao de voce nunca ter lido o livro "Clean Code" ele nao eh a unica fonte de codigo limpo, tem muito conhecimento que pode ser aprendido na internet gratuitamente e ate cursos aqui na alura mesmo que abordam estes assuntos.

Caso tenha qualquer duvida sobre o que eu coloquei aqui pode me perguntar, fico feliz em ajudar :)

Olá, @PedroAppel! Obrigado pela sua resposta.

No momento em que você me respondeu, eu já tinha me desafiado a tentar entender melhor alguns princípios SOLID e a de tentar deixar esse código mais limpo na marra, mesmo sem ter lido o livro. Inclusive, foi até uma afirmação meio estúpida de minha parte, pois não é obrigatório ler o livro para aplicar e aprender os princípios de desenvolvimento de código limpo.


Como essa etapa do projeto ainda é beeem simples, eu pesquisei e cheguei na mesma observação que você pontuou sobre os métodos estáticos e sobre a violação do SRP na UserInterface. Então, me propus a modularizar e segregar todas as atividades que ela estava sendo responsável por fazer em diferentes classes, cada uma com uma única responsabilidade. Meu resultado final ficou assim:

`package br.com.floresdev.screenmatch.application;

import ...;

public class UserInterface {

private final UserInteraction userInteraction;
private final SeriesService seriesService;
private final SeasonService seasonService;
private final EpisodeService episodeService;
private final DisplayService displayService;

public UserInterface(UserInteraction userInteraction, SeriesService seriesService,
                     SeasonService seasonService, EpisodeService episodeService, DisplayService displayService) {
    this.userInteraction = userInteraction;
    this.seriesService = seriesService;
    this.seasonService = seasonService;
    this.displayService = displayService;
    this.episodeService = episodeService;
}

public void start() {
    displayService.showMenu();

    String seriesName = userInteraction.getSeriesName();
    SeriesDataModel series = seriesService.getSeriesByName(seriesName);
    String fullAddress = seriesService.getFullAddress(seriesName);

    int chosenOption = userInteraction.getChosenOption();

    switch (chosenOption) {
        case 1:
            List<SeasonDataModel> seasons = seasonService.getSeasons(series, fullAddress);
            displayService.showSeasons(seasons);
            break;
        case 2:
            int seasonNumber = userInteraction.getSeasonNumber();

            List<EpisodeModel> episodes = episodeService.getEpisodesNames(seasonNumber, fullAddress);
            displayService.showEpisodesNames(episodes);
            break;
        case 3:
            displayService.showTopFiveEpisodes(episodeService.getTopFiveEpisodes(seasonService.getSeasons(series,
                    fullAddress)));
            break;
        case 4:
            displayService.showEpisodesFromYear(episodeService.getEpisodesFromEpisodesData(
                    seasonService.getSeasons(series, fullAddress)), userInteraction.getSearchYear());
            break;
        case 5:
            displayService.showEpisodeByTitle(
                    episodeService.getEpisodeByTitle(
                        episodeService.getEpisodesFromEpisodesData(seasonService.getSeasons(series, fullAddress)),
                        userInteraction.getEpisodeTitle())
            );
            break;
        case 6:
            displayService.showRatingsPerSeason(episodeService.getRatingsPerSeason(
                    episodeService.getEpisodesFromEpisodesData(seasonService.getSeasons(series, fullAddress))
            ));
            break;
        case 7:
            displayService.showStats(episodeService.getStats(
                    episodeService.getEpisodesFromEpisodesData(
                    seasonService.getSeasons(series, fullAddress)
                    ))
            );
            break;
        default:
            System.out.println("Invalid chosen option! Please, follow the correct pattern of choice and " +
                    "try again.");
            start();
    }
}

public UserInteraction getUserInteraction() {
    return userInteraction;
}

}`


Conclusão

Depois de "aplicar na marra", eu sei que pelo menos o SRP entrou na minha cabeça, e foi um desafio muito gratificante ver minha aplicação final melhor estruturada com o fruto do meu esforço. Estou terminando o primeiro curso dessa formação nesse momento e sei que estou "pulando etapas", já que na sequência de formações de desenvolvimento Java existe uma específica que foca nessa parte de boas práticas etc., mas sei que valeu a pena.


De novo, obrigado pelo comentário, e se você quiser dar uma olhada nas classes que criei pra "ajudar" a UserInterface a ter a única função de controlar o fluxo de execução do programa, pode olhar aqui: ScreenMatch Without Web.