Quindi OOP si occupa di abbattere le funzionalità, rendendo ogni classe responsabile di una cosa ecc. Ma prendiamo l'esempio in cui un oggetto sta usando un altro oggetto. La prima cosa che mi viene in mente "composizione, ovviamente!".
Ho 2 domande:
Domanda 1: Supponiamo che tu abbia un negozio che sta caricando prodotti da un file utilizzando un ProductsLoader, che nel termine utilizza un ProductFileReader. Si progetta l'API in modo che il codice sia semplice, leggibile e specializzato. Pertanto, puoi farlo:
std::shared_ptr<Shop> shop = std::shared_ptr<Shop> (new Shop());
shop->LoadProducts();
// other code
In LoadProducts
fai questo:
m_productsLoader.LoadAllProducts();
std::shared_ptr<Products> products = m_productsLoader.GetAllProducts();
this->setProducts(products);
In LoadAllProducts()
fai questo:
prodFileReader.OpenProductsFile();
prodFileReader.LoadDescriptionsFromFile();
prodFileReader.CloseProductsFile();
// create products from descriptions
std::shared_ptr<Descriptions> descriptions = prodFileReader.GetProductsDescriptions();
this->createProductsFromDescriptions(descriptions);
E ora ecco la domanda: mantieni ProductsLoader m_productsLoader
come membro Shop
? Lo stesso per ProductsFileReader
: dovrebbe essere un membro di ProductsLoader
? L'alternativa per questo è la creazione di questi oggetti nello stack: quando le tue funzioni usano uno di essi, devi solo dichiararli, inizializzarli ecc. Nella funzione e vengono distrutti quando la funzione termina. Questo sfugge allo scopo di OOP?
Domanda 2:
Diciamo che hai deciso di tenerli come membri. Come fai a sapere se dovresti mantenere l'intero oggetto come membro, o dovresti tenere solo un puntatore ad esso (e, ovviamente, nel costruttore, istanziare il membro e assegnare il puntatore). Sia che tu acceda al membro con il punto opperator .
o freccia ->
, eseguirà la stessa funzionalità.