Template Methodとは
広く使われているアンチパターンです。
アンチパターンである理由
処理の流れが追いづらくなる
Template Methodパターンは、 サブクラスで実装が必要なメソッドをabstractメソッドとして定義して、 実装の骨格をスーパークラスで行うパターンです。
この分離が適切に行われていないと、 スーパークラスの実装の骨格を見ても何が行われているかが分からず、 逆にサブクラスでどのようなメソッドを実装すべきかが分かりません。
拡張性が制限される
Template Methodパターンは、骨格が変わらないことを前提としているため、 骨格が変わるような仕様変更が入ってしまうと、破綻します。 最初から必要な骨格が分かっていて、変更がないと確信できる場合のみで使うべきです。
(自分から見て)良くない例
以下は継承を使ってない例もありますが、 「骨格のみ提供して自前で実装する」という意味では同じなので載せています。
- HamcrestのMatcher#describeMismatchはどのように実装すればいいか理解できませんでした。
- Matcher#describeMismatchの使用例を見てもさっぱり。。。
- AssertJのカスタムアサーションはコードを見れば分かるので良いです。
- Gson
- Custom Serialization and Deserializationを見てもイマイチよく理解できません。
- MoshiのCustom Type Adaptersの方がシンプルで分かりやすいです。
どのようにすべきか
- Strategyパターンの仕様を検討する。
- どうしてもTemplate Methodの方がふさわしいと思える場合は以下のようにする1。
- メソッドは副作用のない関数にする。
- パラメータ及び戻り値に使用するのはValue Objectとする。
- 「世界」「状態」を渡さない。
- Effective Javaでは、項目16〜18で継承について議論されています。
-
全廃以外は考えたことないので、正しい保証はありません。 ↩︎