5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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 が実行されているのが
分かると思います。

また、fetchDataanalyzeDataformatReport という処理のフローは変わっていないものの
処理の内容を変更することが出来ているのが分かると思います。

最後に

いかがでしたでしょうか。

テンプレートメソッドパターンを利用することで、処理の流れを変えずに部分的な処理の内容のみを変更することができます。

上手く活用して、コードの再利用性を高めていきましょう。

参照

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?