After having some breakthroughs, you realise that the game development is actually sort of a large system development and you had better have full control over the flow. The more you code (especially if you are trying to come up with a common rendering system or a generic library-kinda-thing for your whole future projects) the more you see the importance of the separate interface and implementation.

That’s exactly what template method pattern provides. It lets you define the backbone of your algorithm and gives you some placeholders to specialize them in the derived classes. Thus, interface of the base class (and structure of the algorithm) remains steady, the base class has full control over its interface and policy and now you can enforce interface preconditions and postconditions, insert instrumentation, and perform any similar work all in a single convenient place.

Template method pattern provides you a better separation for the interface and implementation and your base class can handle the future changes and refactors easier since any changes in the implementation won’t bother the common interface at all.

For example consider this example:

This is probably what you have been doing for really long time. And as you can see, this approach causes you the code repetition. Also, it is error prone and adapting to the changes is harder for the common interface.

Remember that virtual methods should be considered as class members. So, they are not supposed to be public unless we really need to have them public. Also consider what Herb Sutter says on his article about virtuality:

  • Guideline #1: Prefer to make interfaces nonvirtual, using Template Method.

  • Guideline #2: Prefer to make virtual functions private. (My note -28/09/2018: If you are working with C# (or should I say Unity?), C# won’t let you to define virtual methods as private. In this case, you will need to go with protected)

  • Guideline #3: Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected.

  • Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.

Thus in our case, it is better to implement a non-virtual public method that defines the common algorithm and call the customizable nonpublic virtual placeholder method(s) at the related part of the algorithm.

So, we will replace our class implementations as below:

References: