📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados em Especialização em Backend com Java e Spring Boot. Recomendado revisar antes de começar.
🎮 Biblioteca de Jogos 02 — Refatoração SOLID/DRY
📁 Código deste projeto:
web-spring/(os caminhos citados abaixo são relativos à subpasta).
Trilha de Aprendizado — Projeto 2 de 4
- 01: CRUD básico de jogos · H2 · Bootstrap 5
- ➡️ 02 (este): Refatoração SOLID/DRY — camada de Service, DTOs, Bean Validation
- 03: Categorias, tema claro/escuro, deploy Render + Neon
- 04: Levantamento de Requisitos · Backlog & Sprints · Git Flow · testes · ADRs
🎓 Nível profissional simulado: Júnior. Nenhuma feature nova em relação ao
_01— só reorganização. Um júnior reconhece dois problemas reais no código anterior e sabe nomeá-los: entidade JPA exposta direto no formulário (sem validação) e controller acessando o repositório sem nenhuma camada de regra de negócio no meio.`
Partir do código do Biblioteca de Jogos 01 e refatorar, sem adicionar feature nenhuma.`
_01// _01 (antes)
@PostMapping("/jogos")
public String adicionar(@ModelAttribute Jogo novoJogo) {
jogoRepository.save(novoJogo);
return "redirect:/";
}
Nada impede o cadastro de um jogo com título vazio — o form HTML tinha required, mas isso só protege contra o usuário usando o navegador normalmente; qualquer requisição HTTP direta (Postman, curl) passa batido.
Fix: NovoJogoDTO com @NotBlank nos dois campos, validado no controller com @Valid + BindingResult, mensagens de erro exibidas no formulário.
// _01 (antes)
@Autowired
private JogoRepository jogoRepository;
@PostMapping("/jogos/{id}/concluir")
public String marcarConcluido(@PathVariable Long id) {
jogoRepository.findById(id).ifPresent(jogo -> { /* ... */ });
return "redirect:/";
}
Fix: JogoService extraído, usado pelo JogoController — hoje os métodos só repassam pro repositório, mas a regra de negócio (ex.: “não permitir apagar um jogo com mais de X horas registradas”) tem onde crescer sem tocar no controller.`
grep -r JogoRepository src/main/java/.../controller/deve vir vazio — só classes emservice/acessam o repositório.- Tente enviar o formulário com o campo “Título” vazio — deve mostrar erro em vez de criar um jogo sem nome.
- O comportamento visível é idêntico ao
_01.`
public class NovoJogoDTO {
@NotBlank(message = "O título é obrigatório")
private String titulo;
@NotBlank(message = "A plataforma é obrigatória")
private String plataforma;
public String getTitulo() { return titulo; }
public void setTitulo(String titulo) { this.titulo = titulo; }
public String getPlataforma() { return plataforma; }
public void setPlataforma(String plataforma) { this.plataforma = plataforma; }
public Jogo toEntity() {
Jogo jogo = new Jogo();
jogo.setTitulo(this.titulo);
jogo.setPlataforma(this.plataforma);
jogo.setConcluido(false);
return jogo;
}
}
cd catalogo_projetos/javaweb_jogos_02_dto/web-spring
./mvnw spring-boot:run
No Windows (PowerShell):
cd catalogo_projetos\javaweb_jogos_02_dto\web-spring
.\mvnw.cmd spring-boot:run
http://localhost:8080/.No seu editor/IDE, abra a pasta deste projeto (File > Open Folder) ou navegue via terminal:
cd javaweb_jogos_02_dto
./mvnw spring-boot:run
./mvnw test
[!TIP] Dica para execução a partir da raiz do repositório: Se você abriu o repositório completo no VS Code, basta navegar até a pasta antes de executar: cd catalogo_projetos/javaweb_jogos_02_dto