親クラスで枠組みを決めて、具体的な処理は子クラスで実装するもの。親クラスでテンプレートとなるメソッドを抽象メソッドで定義し、具体的な処理は子クラスで実装する。
アルゴリズム的な部分は一緒だけど、具体的な部分は異なるような場合、コピーペーストで複数のクラスを作ってしまうと、アルゴリズムのどこかに変更があった場合、すべてのクラスを修正しなくてはならない。そこで親クラスを抽象クラスとしてアルゴリズムを記述し、具体的な部分は子クラスで実装するようにすればよい。そうすれば、アルゴリズムが変更された場合は親クラスのみを修正するだけで済む。
たとえば、Read()して何らかの処理を行い、Write()するような処理があり、Read()やWrite()の対象が変わって処理が異なるような場合は次のような感じで書ける。
class Base { public: void Read() = 0; void Write() = 0; void Exec() { Read(); ... Write(); } }; class TestA : public Base { public: void Read() { ... } void Write() { ... } }; class TestB : public Base { public: void Read() { ... } void Write() { ... } }; void doTest() { Base test0 = new TestA(); Base test1 = new TestB(); test0.Exec(); test1.Exec(); }
(このソースはイメージを表したもので、実際にはこのまま入力しても動作しない)
Read()やWrite()の処理は子クラスで実装することによって、デバイスやファイルが変わっても親クラスのExec()のアルゴリズムは変更する必要はない。
どこまでを親クラスで実装し、どこからを子クラスで実装するかというのが結構難しそうだ。
参考文献:Java言語で学ぶデザインパターン入門
参考:
ギコ猫とTemplate Methodパターン
Template Method パターン - Wikipedia