The clients can extend their profile over various screens in their account, like status, settings, etc.
Perché non seguire il linguaggio ubiquitario / commerciale e avere un aggregato di clienti? Questo aggregato può essere composto da un oggetto valore AccountSettingsList, un oggetto valore Person (che contiene nome completo, indirizzo o altre informazioni relative alla persona), un oggetto valore Status. Perché dovrebbero essere oggetti di valore? Perché non sembra esserci alcuna ragione in generale per loro di avere identità all'interno dell'aggregato, sono semplicemente identificati dalle loro proprietà / descrittori.
These data sets are saved in seperate database tables by a WordPress plugin
Da una prospettiva di progettazione basata sul dominio, quando si costruisce il proprio modello / oggetto di dominio si dovrebbe cercare di mantenere qualsiasi progetto relativo alla persistenza. Ma se il plugin Wordpress impone i contratti / design dei tuoi oggetti allora forse la modellazione di domini non è l'approccio migliore e dovresti semplicemente seguire la progettazione che il plugin Wordpress si aspetta (progettare in base ai contratti in un modo e in questo caso forse il plugin di Wordpress detta che tipo di oggetti / strutture dati si aspetta).
Ma se il plugin Wordpress si occupa solo della logica di persistenza, forse dovresti semplicemente usarlo come un livello di astrazione del database.
Now I need a way to display these user related data sets in the frontend.
Potresti usare gli oggetti del tuo modello di dominio direttamente nelle tue viste (template html o oggetti json), oppure potresti avere modelli di visualizzazione dedicati e servizi che costruiscono questi modelli di visualizzazione dal database quando sono necessari (in questo modo ti limiti a codificare i modelli di vista in json e passali al client se è un tipo API REST). Ma il modo più semplice è quello di utilizzare in qualche modo i modelli di dominio direttamente nelle visualizzazioni (inserire alcuni getter nei modelli di dominio per rendere disponibili per le viste tutti i dati nei propri aggregati).
So I was thinking of creating a client aggregate root (which is the client entity basically) and a bunch of entity objects:
Non importa quanto tu chiami le tue entità / oggetti valore purché tu capisca di cosa ha bisogno il dominio. Penso che tu sia sulla strada giusta. Le entità / oggetti di valore che ho elencato sopra sono simili.
Question 1: Does this approach make sense?
Sì, penso che tu sia sulla strada giusta.
Question 2: How are aggregates actually assembled? Does this happen in the UserRepository? I couldn't find any PHP code examples.
Sì, dovrebbero essere ricostituiti da un repository. Per non ingombrare il livello del tuo modello di dominio con la logica del database, puoi avere un contratto nel tuo livello dominio (un'interfaccia) in cui definisci i metodi per recuperare e salvare il tuo aggretato e in un altro livello (come diciamo persistenza o livello infrastruttura) avere l'effettiva implementazione di queste interfacce. E utilizzare l'iniezione / inversione di dipendenza per il controllo per iniettare queste implementazioni del repository nei servizi dell'applicazione.
Question 3: Since there's quite a lot of data in ie. Settings apar...
Suppongo che i dati delle tue impostazioni siano statici, come te e non i tuoi utenti decidono quali sono queste impostazioni. Se questo è vero, allora non vedo alcun problema qui. Non tutti quei dati. Nei tuoi repository hai solo metodi come: findById, findByEmail (tutti restituiscono uno o più aggregati client), un metodo di salvataggio (che salverebbe un aggreagate nuovo o modificato) e forse un metodo di rimozione / eliminazione (che eliminerebbe un aggregato ). I repository sono oggetti semplici, recuperano e salvano solo aggragates nel loro complesso. Non hai bisogno di metodi separati per ogni oggetto entità / valore in un aggreagate. Ancora una volta dovresti trovare / salvare aggreagtes nei tuoi repository nel loro complesso.
Repository di esempio:
ClientRepository implements IClientRepository {
public function findById(ClientId $id) : Client;
public function findByEmail(Email $anEmail) : Client;
public function save(Client $aClient) : void;
}
Ora, quando si tratta di salvare le modifiche di un aggreagte, è necessario monitorare in qualche modo i cambiamenti che si verificano nei tuoi aggreagate, t eh modifiche alle loro proprietà. Approfitta di una dottrina ORM che semplifica le cose, o in qualche modo traccia le tue modifiche e confronta il vecchio aggreagate con quello nuovo nei tuoi repository e salva le modifiche. Puoi anche avere 2 metodi separati come saveNew e saveModifications se decidi di tenere traccia delle modifiche da solo.