9.9 Template Method
The Template Method Pattern is a very well-known pattern described in much greater detail in many sources, such as the classic book Design Patterns by Gamma et al. Its intent is to outline an algorithm in an operation. The Template Method Pattern allows subclasses to retain the algorithm's structure while permitting redefinition of certain steps of the algorithm. We are including a simple description of this pattern here, because it is one of the most commonly used patterns in API frameworks.
The most common variation of the pattern consists of one or more nonvirtual (usually public) members that are implemented by calling one or more protected virtual members.
public Control{ public void SetBounds(int x, int y, int width, int height){ ... SetBoundsCore (...); } public void SetBounds(int x, int y, int width, int height, BoundsSpecified specified){ ... SetBoundsCore (...); } protected virtual void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified){ // Do the real work here. } }
The goal of the pattern is to control extensibility. In the preceding example, the extensibility is centralized to a single method (a common mistake is to make more than one overload virtual). This helps to ensure that the semantics of the overloads stay consistent, because the overloads cannot be overridden independently.
Also, public virtual members basically give up all control over what happens when the member is called. This pattern is a way for the base class designer to enforce some structure of the calls that happen in the member. The nonvirtual public methods can ensure that certain code executes before or after the calls to virtual members and that the virtual members execute in a fixed order.
As a framework convention, the protected virtual methods participating in the Template Method Pattern should use the suffix "Core."
AVOID making public members virtual.
If a design requires virtual members, follow the template pattern and create a protected virtual member that the public member calls. This practice provides more controlled extensibility.
CONSIDER using the Template Method Pattern to provide more controlled extensibility.
In this pattern, all extensibility points are provided through protected virtual members that are called from nonvirtual members.
CONSIDER naming protected virtual members that provide extensibility points for nonvirtual members by suffixing the nonvirtual member name with "Core."
public void SetBounds(...){ ... SetBoundsCore (...); } protected virtual void SetBoundsCore(...){ ... }
The next section goes into designing APIs that need to support timeouts.