Template Method とは?
そもそも Template って?
そもそも Template とはなんでしょう。
「雛形」や「型板」といった意味を持つ英単語になります。
例として、挙げると デザインのテンプレートや契約書のテンプレートなどがあります。
Template を使う 理由として、
- 類似したものを簡単に作ることができる
- 具体の内容は変更できる
といったものがあります。
さて、Template Method の説明に入ります。
スーパークラス(親クラス)で処理の骨組みを定義し、サブクラス(子クラス)は構造を変更することなく具体的な内容を定義することができるデザインパターンです。
Template Method の構成要素
AbstractClass(抽象クラス)
- 処理全体の流れを決定するテンプレートメソッド
- テンプレートメソッドで使用する抽象メソッド
ConcreteClass
- AbstractClass を継承したクラス
- AbstractClass で定義された抽象メソッドを実装する
Template Method のメリット
- 共通な処理を親クラスにまとめることができる
- 処理全体の流れは変えずに、子クラスごとに一部の処理内容を変更することできる
Template Method のデメリット
- 子クラスで親クラスのメソッドの振る舞いを変えてしまうとリスコフの置換原則に違反する
- 親クラスの処理が大きくなると、子クラスの処理の自由が制限される
実装例
さて、今回は TypeScript で Template Method を実装してきます。
JavaScriptには実装されていませんが、TypeScriptには抽象クラス (abstract class)
が実装されているので今回はそれを使用していきます!
abstract class について知りたい方は
をご覧ください。
export {}
abstract class ReportTemplate {
generateReport() {
this.fetchData();
this.analyzeData();
this.formatReport();
this.printReport();
}
abstract fetchData(): void;
abstract analyzeData(): void;
abstract formatReport(): void;
printReport() {
console.log("Report printed");
}
}
class SalesReport extends ReportTemplate {
fetchData() {
console.log("Fetching sales data");
}
analyzeData() {
console.log("Analyzing sales data");
}
formatReport() {
console.log("Formatting sales report");
}
}
class InventoryReport extends ReportTemplate {
fetchData() {
console.log("Fetching inventory data");
}
analyzeData() {
console.log("Analyzing inventory data");
}
formatReport() {
console.log("Formatting inventory report");
}
}
function run() {
const salesReport = new SalesReport();
const inventoryReport = new InventoryReport();
salesReport.generateReport();
console.log("");
inventoryReport.generateReport();
}
run();
上記を実行すると、以下が出力されます。
Fetching sales data
Analyzing sales data
Formatting sales report
Report printed
Fetching inventory data
Analyzing inventory data
Formatting inventory report
Report printed
salesReport と の inventoryReport 両方で printReport が実行されているのが
分かると思います。
また、fetchData
→analyzeData
→formatReport
という処理のフローは変わっていないものの
処理の内容を変更することが出来ているのが分かると思います。
最後に
いかがでしたでしょうか。
テンプレートメソッドパターンを利用することで、処理の流れを変えずに部分的な処理の内容のみを変更することができます。
上手く活用して、コードの再利用性を高めていきましょう。
参照