5.7 Factoring of Base Classes


Developing a derived class may lead to redesign of the base class. The base class is redesigned so that the derived class can be accomodated without sacrificing the integrity of the base class. In general, the interface between the base class and its derived classes is as important, and requires as much effort to develop and maintain, as the interface between an object and the object's clients.

An example of where base class redesign is needed occurs in developing an OctalCounter class. An OctalCounter object is just like a Counter object except that the OctalCounter object's value is displayed using octal number notation and not as a decimal value. For example, the decimal value "23" would be displayed in its octal representation as "27".

While most of the methods in the Counter and DisplayableNumber classes are exactly those needed to implement an OctalCounter, the Show method is inappropriate because it displays values in a decimal notation. The inherited Show method must be replaced (overriden) by a Show method that displays the value in octal notation.

However, overriding the show method leads to a dilemma regarding the sharing of data between the base and derived class. The Show method uses the textBox variable to display the DisplayableNumber's current value. To override the Show method in a derived class, the textBox variable must be placed in the protected region of the base class. This change, while workable, significantly enlarges the scope (i.e., weakes the protection) of the textBox variable. The base class no longer completely encapsulates the existance of the textBox variable. Therefore, both the base class and its derived classes are dependent on the following design decisions:

If any of these design decisions change, then both the base class and all of its derived subclasses are vulnerable to change. Notice how serious a problem this is: a derived class (OctalCounter) may need to be changed because of a change in a class (TextBox).

The cause of the problem is that the Show method performs two related, but seperable, actions:

The design dilemma is easily resolved by recognizing that the OctalCounter class only needs to override the first action, and only the second action requires knowledge of the TextBox class and the textBox variable. A new virtual method, char* Format(), is added to the base class to perform the first action. The revised Show() method will use the Format method.

Separating the two actions of the Show method leads to the following code:


   class DisplayableNumber {
    private:
      TextBox* textBox;
    protected:
      int value;
      virtual char* Format();		// take value produce string to display
    public:
      DisplayableNumber(int initValue = 0);   
      void ShowIn(TextBox& p);
      void Show();
      void Reset();
      ~DisplayableNumber();

   };

   char* DisplayableNumber::Format() {		
       char* asString = new char[10];
       sprintf(asString, "%10d", value);
   }

   void DisplayableNumber::Show() {
        if (textBox) textBox->SetText(Format());
   }

Exercises

None as yet.

Last Updated: March 26, 1996 / kafura@cs.vt.edu