Supponiamo di avere 2 classi: account e contatti come questo:
class Account {
string Id;
string Name;
}
class Contact {
string Id;
string FirstName;
string LastName;
}
Un account può contenere molti contatti. Questi dati sono gestiti in una classe "DataManager" che funge da repository per il resto del programma. Ci sono 2 requisiti principali:
- Per un account, ho bisogno di recuperare un elenco dei suoi contatti
-
Per un dato accountId o contactId ho bisogno di recuperare il rispettivo account / contatto. Il recupero di un contatto dovrebbe funzionare, anche se non so a quale account è stato assegnato il contatto. In questo modo
Contatti c = dataManager.GetContact (contId);
Ho discusso con un collega le seguenti 2 opzioni per implementare la relazione Account-Contatto in C ++:
Opzione 1: archivia gerarchicamente ... la classe Account conterrà una mappa di contatti. La chiave di quella mappa sarebbe il ContactId. Il DataManager memorizzerebbe una mappa di account:
class DataManager {
Account& GetAccount(string accountId);
Contact& GetContact(string contactId);
map<string, Account> accounts;
}
class Account {
map<string, Contact> contacts;
Contact& GetContact(string contactId);
list<reference_wrapper<Contact>> GetContacts();
}
Problema: l'implementazione di DataManager :: GetContact dovrebbe essere ripetuta su tutti i contatti dell'account. In alternativa, potrei memorizzare una mappa di contactId - > accountId in DataManager per trasferire rapidamente l'account che contiene il contatto richiesto.
Opzione 2: "Archiviazione piatta" In questa soluzione, gli oggetti sono tutti memorizzati nel DataManager. La classe account memorizza solo Id dei suoi contatti.
class DataManager {
map<string, Account> accounts;
map<string, Contact> contacts;
Account& GetAccount(string accountId);
Contact& GetContact(string contactId);
}
class Account {
map<string, string> contactIds;
list<string> GetContactIds();
}
Problema: per ottenere un elenco di tutti i contatti di un account, il codice chiamante (- > in real: un codice nel DataManager) deve scorrere l'elenco di contactId recuperati dall'oggetto Account e raccogliere il rispettivo contatto oggetti dal DataManager.
Opzione 2.1 Riferimento wrapper Per quanto riguarda i contenitori che utilizzano reference_wrapper anziché string contactId? (come suggerito da @Caleth)
Che cosa fare? Quale di queste opzioni ti sembra più legittima? Oppure suggerisci una soluzione diversa?