Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Use the Template Design Pattern to Customize a Base Class Service in a Derived Class-3 : Page 3


advertisement
Implementation
In essence, the Template design pattern separates between mandatory primitive operations (which are implemented in the base class) and hooks for customized operations that a subclass may redefine later. Following these guidelines, the modified Viewer class now looks like this:

class Viewer { public: int Open(const char * filename) { init();//mandatory steps: CRC check, authorization if (is_custimized() ) customized_init();//allow customization by subclasses } virtual ~Viewer(); protected: //hooks for a subclass's customizations virtual bool is_custimized()=0; virtual void customized_init() {} private: //mandatory primitive operations void init(); };

When a subclass overrides a protected member function, it changes that function's access to private:

class MyViewer: public Viewer { //.. private: bool is_custimized() const; void customized_init(); }

The Well-Tempered Template
How does it work? A subclass that wishes to retain the base class' functionality as-is shall provide a trivial implementation of is_customized():


bool is_customized() const {return false;)

When a subclass object calls Open(), it always executes Viewer::Open() because this function isn't virtual. Open() in turn invokes init() to perform the mandatory primitive operations and then calls the subclass' is_customized(). A subclass that wishes to customize the behavior of Open() must change the return value of is_customized() to true and override customized_init() as necessary.

A Template Recipe
Let's summarize the design principles of a Template function:

  • A Template function is a nonvirtual public member function that performs a series of primitive operations.
  • Some of the primitive operations are mandatory; others may be customizable.
  • Mandatory operations are nonvirtual private members of the base class.
  • Customized primitive operations are declared virtual protected in the base class, but change their access to private in a subclass.
  • Customizable primitive operations that must be overridden are declared pure virtual in the base class; those that may be overridden are declared virtual.
In addition to the obvious benefit of providing a skeletal implementation in the base class while allowing a subclass to redefine certain portions thereof, the Template design pattern minimizes the number of primitive operations that a derived class must perform to flesh out the Template function. In this example, a derived class merely provides a trivial definition of is_customizable() to retain the base class functionality.



Danny Kalev is a certified system analyst and software engineer specializing in C++. He was a member of the C++ standards committee between 1997 and 2000 and has since been involved informally in the C++0x standardization process. He is the author of "The ANSI/ISO Professional C++ Programmer's Handbook" and "The Informit C++ Reference Guide: Techniques, Insight, and Practical Advice on C++."
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap