Duda sobre como manejar una dependencia cíclica

fvksys

Antes de nada especificar que se trata de un proyecto con Spring Boot. Al grano:

Para evitar dependencias cíclicas, se pueden/deben inyectar otras clases de la capa de servicio en otro servicio o debería trabajar siempre sobre los repositorios?

Voy a poner el ejemplo del caso con el que me encuentro:

Tengo dos clases: GameService (GS) / PlayerService (PS)

Desde PS quiero obtener un Game y comprobar que existe, llamo a un método de GS que me sirve partidas y viceversa, desde GS tengo un método en PS que me sirve jugadores.

En este caso sería mejor pedirlo al repositorio, a pesar de que en estos métodos de la capa servicio ya tengo las excepciones controladas (Juego no existe, juego finalizado...), evitando código boiler plate?

Espero haberme explicado, que aun estoy un poco verde...

Flashk

Si las dependencias las inyectas mediante constructor puede darte problemas. Con otros tipos de inyección no tendrás problemas, ya que Spring inyectará las dependencias cuando las necesites.

Este artículo puede serte de ayuda y explica como resolver todo esto:
https://www.baeldung.com/circular-dependencies-in-spring

1
bornex

La inyección de dependencias siempre por constructor, en el peor de los casos usar los setters y raras veces (o ninguna) por atributo. ¿Porqué? La principal razón es el testing, pero evitar NullpointerExceptions (cuando te olvidas de setear un atributo de la clase por ejemplo), tener inmutabilidad, etc... suelen ser algunas otras.

¿Has intentado usar composición? Puedes crear GS independientemente de PS (y viceversa) y luego crear una tercera clase que contenga a las dos y haces lo que necesitas.

Kaledros

Creas PlayerRepository y GameRepository, los inyectas los dos en cada service y a marchar. No pasa nada si GS tiene una funcionalidad relacionada con players y viceversa, la funcionalidad sigue siendo del juego y por tanto va en GS.

JuAn4k4

Es que no es GameService ni PlayerService. El problema viene de diseño.

Tendrás un MatchingSystem en todo caso que te empareje jugadores para las partidas. Y no un PlayerService que engloba muchas cosas.

Podrías tener PlayerMetadataService solo para leer los meta datos de los jugadores, pero el emparejamiento para una partida es otra cosa.

Y se acaba tu dependencia circular

2 1 respuesta
fvksys

#5 Pues sí, lo estoy replanteando así. Hasta ahora había trabajado en proyectos mas simples y para los servicios creaba clases que englobaban varias funcionalidades relacionadas con X modelo.

Usuarios habituales

  • fvksys
  • JuAn4k4
  • Kaledros
  • bornex
  • Flashk