Design Patterns: The Template Method Pattern and Final Methods

C# got it wrong. Java got it right.

C# doesn’t let you “seal” methods that aren’t overridden. Java allows you to mark any method as “final” – whether it’s an overridden method or not. This subtle detail has interesting implications.

The Gang of Four’s “Design Patterns: Elements of Reusable Object-Oriented Software” was published in 1994—many years before C# was first released and just two years before Java was released. (Although, most of the code in the book was presented in C++.) The book presents the “Template Method” behavioral pattern. Template methods define the “framework” of an algorithm and leave subclasses to define the behavior. Unfortunately, if you cannot mark a template method as ‘final’ (or ‘sealed’ in C#), it enables subclasses to—potentially by accident—change the behavior of the template method.

Here’s a template method in action, written in JS++, to demonstrate how this might be undesirable:

abstract class Model
{
	abstract public bool validate();
	abstract protected void saveTemplate(IDatabase db);
	public final void save(IDatabase db) {
		if (!this.validate()) {
			throw new ValidationException();
		}

		this.saveTemplate(db);
	}
}

In the above class, the template method (“save”) is marked as ‘final’. Without ‘final’, an overriding method (or overwriting method, to use JS++ terminology) can potentially forget to perform business object validation before altering the database. This can lead to potential bugs and security threats.

Beginning with the next release of JS++, you will be able to mark any method as ‘final’.