So OOP is about breaking down functionality, making each class responsible for o
ID: 659075 • Letter: S
Question
So OOP is about breaking down functionality, making each class responsible for one thing etc. But let's take the example where an object is using another object. First thing that comes to mind "composition, of course!".
I have 2 questions:
Question 1: Suppose you have a Shop that is loading products from a file using a ProductsLoader, which in term uses a ProductsFileReader. You design the API so that the code is simple and readable and specialized. Therefore, you are able to do this:
std::shared_ptr<Shop> shop = std::shared_ptr<Shop> (new Shop());
shop->LoadProducts();
// other code
In LoadProducts you do this:
m_productsLoader.LoadAllProducts();
std::shared_ptr<Products> products = m_productsLoader.GetAllProducts();
this->setProducts(products);
In LoadAllProducts() you do this:
prodFileReader.OpenProductsFile();
prodFileReader.LoadDescriptionsFromFile();
prodFileReader.CloseProductsFile();
// create products from descriptions
std::shared_ptr<Descriptions> descriptions = prodFileReader.GetProductsDescriptions();
this->createProductsFromDescriptions(descriptions);
And now here is the question: Do you keep ProductsLoader m_productsLoader as a Shop member? The same for ProductsFileReader: should it be a member of ProductsLoader? The alternative for this is creating these objects on the stack: when your functions are using one of them, you just declare, initialize etc them in the function and they get destructed when the function exits. Does this defy the purpose of OOP?
Question 2: Let's say you decided to keep them as members. How do you know wheter you should keep the whole object as a member, or you should keep only a pointer to it (and, of course, in the constructor, instantiate the member and assign the pointer). Whether you access the member with the dot opperator . or arrow ->, it will perform the same functionality.
Explanation / Answer
I would usually keep the collaborator objects as pointer members in the object that will use them. I would also usually have them implemented using an abstract class and pass the pointers as parameters to Shop's constructor rather than having Shop building them itself. This decouples Shop from the detail of how products are loaded, and means I can change to a different source of Products without needing to modify Shop; this is the fundamental essence of the Open/Closed principle, which some people describe as the most important principle on object-oriented design.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.