Dalla mia esperienza penso che avere classi / modelli senza comportamento solo nella mia applicazione, accanto ai loro repository non sia un buon OOP. Ma questo è il modo in cui ho implementato il modello di repository. Faccio in modo che ovunque io abbia bisogno di un'istanza di repository, per eseguire alcune azioni. Il risultato di questo approccio era che tutte le mie classi di dominio non avevano un comportamento.
Erano solo oggetti contenenti dati senza metodi. La mia insegnante mi ha detto che stavo usando modelli sottili e che dovevo sforzarmi di creare modelli grassi. In risposta a questo feedback, ho implementato alcune logiche di business nelle classi, ma ho riscontrato alcuni problemi:
Esempio:
public class Movie
{
private MovieRepository movieRepo = new MovieRepository(new MovieDbContext());
private PostRepository postRepo = new PostRepository(new PostDbContext());
public decimal Rating { get; set; }
public List<Post> Posts { get; set; }
public void Rate(User user, Movie movie)
{
if(movie.Rating < 0 || movie.Rating > 10)
{
throw new Exception("The rating must be a digit between 0 and 10");
}
this.Rating = movie.Rating;
movieRepo.RateMovie(user.Id, movie.Id, (int)movie.Rating);
}
public void AddPost(User user, Movie movie, string text)
{
int maxId = 0;
foreach (Post p in Posts)
{
if (p.Id > maxId)
{
maxId = p.Id;
}
}
Post post = new Post(maxId + 1, user, text, DateTime.Now);
this.Posts.Add(post);
postRepo.AddPost(user.Id, movie.Id, text, DateTime.Now);
}
}
Come puoi vedere nell'esempio sopra, prima gestisco alcune logiche di dominio, per eseguire azioni sulla classe stessa e poi lo mantengo nel database usando un repository. Ma perché sto addirittura aggiungendo i post alla classe stessa nel metodo AddPost, quando lo gestisco con un repository subito dopo?
Questo è solo perché ora puoi effettivamente vedere le modifiche apportate direttamente sullo schermo, in memoria? Oppure lo scopo della logica di business è solo quello di convalidare l'input del parametro, come mostrato nel metodo Rate del film? Ma questo tipo di eccezioni può anche essere gettato nel repository se il metodo del repository controlla anche se una cifra è compresa tra 0 e 10. Ma penso che un repository non dovrebbe preoccuparsi di ciò. Il repository ha solo bisogno di tradurre input in informazioni di database, ho ragione?
Ma detto questo, non capisco esattamente la necessità di eseguire modifiche sull'oggetto stesso, quando lo gestisci con un repository. Invece di ciò, è possibile (in qualsiasi punto dell'applicazione, per visualizzare l'oggetto utente):
postRepo.AddPost(2, 1, "Nice movie!", DateTime.Now);
User user = userRepo.GetById(2);
Quali sono i pro e i contro di questa differenza?