Suppose I have a C++ application for a pet store that started out just with Cats. The app has a class that does some data handling for a Cat dialog box:
CatDlg.cpp:
CatDlg::CatDlg() {//ctor stuff}
CatDlg::onInitDialog() {
DBAccess db;
db.open();
CatRec cat;
cat = db.findRec(m_catID);
CString name = cat.getName();
NameField.SetWindowText(name);
// other catty dialogy stuff
}
Now the store owner wants to add Dogs to the application. Dog data is essentially the same as Cat data, except for data types. I could just duplicate the CatDlg class, change a few types and handle it this way, but that leads to maintenance issues and code bloat with 99% duplicated code:
DogDlg.cpp:
DogDlg::onInitDialog() {
DBAccess db;
db.open();
DogRec dog;
dog = db.findRec(m_dogID);
CString name = dog.getName();
NameField.SetWindowText(name);
// other doggy dialogy stuff
}
Or, I could change the dialog class to handle multiple animals, by passing in a flag that indicates the type of animal, then process it accordingly. THis also gets uglier as the owner add new animals, because the method gets longer, with lots of duplicated code blocks:
AnimalDlg.cpp:
AnimalDlg::onInitDialog(AnimalType type) {
DBAccess db;
db.open();
if(type == CAT)
{
CatRec cat;
cat = db.findRec(m_catID);
CString name = cat.getName();
}
else if(type == DOG)
{
DogRec dog;
dog = db.findRec(m_dogID);
CString name = dog.getName();
}
NameField.SetWindowText(name);
}
What's the best way to refactor the class to make it more general? Is there a design pattern that I can apply? Is there some way to pull the common code into a base class, then make animal-specific subclasses? I had a quick look through Fowler's book on Refactoring, but nothing leapt out at me.
Assume there is lots more code in the class, at the moment specific to the Cat type, but applicable to any type of animal.
Thanks for your help!
Philip