Search

When to ease off on Design Abstraction

INTENTION:

You have a basket. You want to add Sandwiches and Sodas while keeping a separate list for each item that are added to the Basket. You don't want the user to worry about two separate functions, addSandwich( ) and addSodas( ). You want to make the "add" easy for the user, so you decide to abstract away the design of your add function. All good.
 
You derive the Sandwich and the Soda class from a polymorphic Item class and pass that to the add function. ( Note: A polymorphic class has at least one virtual function, usually the Destructor if you can't find another function to do that job for you!) 
 
class CSandwich : public Item {...};
class CSoda : public Item {...} ;
 
void CBasket::add(Item *pItem){...}
 

PROBLEM:

In your add function, you want to keep track of the number of Sandwiches and Sodas being added. Do you do a dynamic cast to find out during run-time what the user is trying to add ?
 
void CBasket::add(Item *pItem)
{
if(dynamic_cast<CSandwich *>(pItem))
//add to the list of sanwiches
 
else if(dynamic_cast<CSoda *>(pItem))
//add to the list to sodas
}
 
Don't do this. You're trying to abstract away too much with one function.
 

SOLUTION:

A better way is to use function overloading. Take the polymorphism idea and put it into your add function.
 
void CBasket::add(CSandwich *pSandwich)
{
//add to the list of sandwiches
}
 
void CBasket::add(CSoda *pSoda)
{
//add to the list of Sodas
}
 
You still have only one add function but a much better design!
 
if (isMyPost) { }