L'uso estensivo del "servizio" è indicativo di una cattiva OOP. Tuttavia, la natura dello sviluppo a volte rende inevitabili le classi di servizio, come nel tuo caso.
La tua entità utente non dovrebbe essere responsabile per la memorizzazione o il recupero stesso; conservare se stesso non viola OOP, tuttavia, viola molte buone pratiche architettoniche come la separazione delle preoccupazioni e il principio di responsabilità singola. Consentire a un oggetto di archiviarlo e recuperarlo automaticamente renderà l'applicazione molto fragile e difficile da mantenere.
Avrai bisogno di un servizio di archiviazione e recupero; tuttavia, etichettarlo semplicemente come un servizio è un po 'pigro. OOP parla di nomi che verbo; rendiamo questo servizio un po 'più OOP ...
Un oggetto che è responsabile solo di CRUD è chiamato repository. Dovrebbe non contenere qualcosa di diverso dai metodi CRUD. Se trovi che il tuo repository ha un metodo come GiveUserPermission stai violando il pattern del repository, non appartiene a questo; appartiene alla classe User o alla classe Mediator di Utente e Autorizzazione. Ogni entità dovrebbe avere il proprio repository. Un repository non dovrebbe essere responsabile per più entità. E ricorda, è per entità, non per tabella.
È irrilevante che il proprio repository ottenga i propri dati da un database o da una chiamata di riposo http; il resto della tua applicazione dovrebbe essere ignorante in questo dettaglio.