テンプレート メソッド パターン - アルゴリズムを定義するためのフレームワーク

1 はじめに

1.1. 概要

テンプレートメソッドパターンは最も単純な構造の動作設計パターンであり、その構造には親クラスとサブクラスの継承関係のみが存在します。テンプレート メソッド パターンを使用すると、一部の複雑なプロセスの実装手順を一連の基本メソッドにカプセル化できます。抽象親クラスにテンプレート メソッドと呼ばれるメソッドを提供して、これらの基本メソッドの実行順序を定義し、そのサブクラスでいくつかのステップをカバーすることで、同じアルゴリズム フレームワークでも異なる実行結果が得られるようにします。テンプレート メソッド パターンは、アルゴリズム フレームワークを定義するためのテンプレート メソッドを提供し、いくつかの特定のステップの実装はそのサブクラスで完了できます。

テンプレート メソッド パターンは、継承に基づいてコードを再利用するための基本的な手法です。

1.2. 定義

テンプレート メソッド パターン: 操作内のアルゴリズムのスケルトンを定義し、一部のステップをサブクラスに延期します。テンプレート メソッド パターンを使用すると、アルゴリズムの構造を変更せずに、サブクラスでアルゴリズムの一部の特定のステップを再定義できます。テンプレート メソッド パターンは、クラスの動作パターンです。

2. 分析

2.1、UML クラス図

テンプレート メソッド パターンの構造は比較的単純です。その中心となるのは、抽象クラスとその中のテンプレート メソッドの設計です。その構造を次の図に示します。
ここに画像の説明を挿入

  1. AbstractClass (抽象クラス): 抽象クラスには一連の基本操作 (プリミティブ操作) が定義されており、これらの基本操作は具象または抽象にすることができます。各基本操作はアルゴリズムのステップに対応しており、これらのステップはサブクラスで再定義または実装できます。同時に、アルゴリズムの枠組みを定義するためのテンプレートメソッド(Template Method)を抽象クラスに実装します。テンプレートメソッドは、抽象クラスに実装されている基本メソッドを呼び出すだけでなく、抽象クラスのサブクラスに実装されている基本メソッドを呼び出したり、他のオブジェクトのメソッドを呼び出すこともできます。
  2. ConcreteClass (具象サブクラス): 抽象クラスのサブクラスであり、親クラスで宣言された抽象的な基本操作を実装して、サブクラス固有のアルゴリズムのステップを完了するために使用されます。また、すでに実装されている具体的な基本操作もカバーできます。親クラスで。

2.2、テンプレートメソッドと基本メソッド

テンプレート メソッド パターンを使用する場合、抽象クラスを開発するソフトウェア設計者と具体的なサブクラスを開発するソフトウェア設計者の間でコラボレーションが行われます。1 人の設計者はアルゴリズムの概要とフレームワークを与える責任を負い、他の設計者はアルゴリズムのさまざまな論理ステップを与える責任を負います。これらの具体的な論理ステップを実現する方法が基本メソッドであり、これらの基本メソッドを組み合わせた方法がテンプレート メソッドであるため、テンプレート メソッド パターンと呼ばれます。

  1. テンプレート メソッド: テンプレート メソッドは、基本的な操作メソッドを組み合わせて全体的なアルゴリズムまたは全体的な動作を形成する抽象クラスで定義されたメソッドです。このテンプレート メソッドは抽象クラスで定義され、変更することなくサブクラスに完全に継承されます (Java 言語では、テンプレート メソッドは最終メソッドとして定義できます)。テンプレート メソッドは、最上位の論理フレームワークを提供する具象メソッドであり、論理構成ステップは具象メソッドまたは抽象クラス内の抽象メソッドにすることができます。テンプレート メソッドは具象メソッドであるため、テンプレート メソッド パターン内の抽象化層は、インターフェイスではなく抽象クラスのみにすることができます。
  2. 基本メソッド: 基本メソッドは、アルゴリズムの各ステップを実現するメソッドであり、テンプレート メソッドの不可欠な部分です。基本メソッドは、抽象メソッド(Abstract Method)、具象メソッド(Concrete Method)、フックメソッド(Hook Method)の 3 種類に分類できます。

(1) 抽象メソッド: 抽象メソッドは抽象クラスによって宣言され、その具体的なサブクラスによって実装されます。抽象メソッドは、Java 言語の abstract キーワードによって識別されます。
(2)具象メソッド:具象メソッドは、抽象クラスまたは具象クラスによって宣言および実装され、そのサブクラスは上書きまたは直接継承できます。
(3) フックメソッド: フックメソッドは、抽象クラスまたは具象クラスによって宣言および実装され、そのサブクラスが拡張される場合があります。通常、親クラスで指定された実装は空の実装であり、この空の実装はメソッドのデフォルト実装として使用されます。もちろん、フック メソッドは空ではないデフォルト実装を提供することもできます。

テンプレートメソッドパターンには2種類のフックメソッドがあります。最初のタイプのフック メソッドは、いくつかの特定のステップを「フック」して、さまざまな条件下でテンプレート メソッドのさまざまなステップを実装できます。この種のフックメソッドの戻り値の型はブール型であることが多く、メソッド名はis×××()という条件を判定するために使用されるのが一般的です。ステップは、条件が満たされた場合に実行され、そうでない場合は実行されません。コードスニペットは次のとおりです。

// 模板方法
public void template(){
    
    
  open();
  display();
  if(isPrint()){
    
    
     print();
  }

  // 构子方法
  public boolean isPrint(){
    
    
     return true;
  }
}

上記のコードでは、isPrint() メソッドはフック メソッドであり、print() メソッドが実行されるかどうかを決定できます。通常の状況では、フック メソッドの戻り値は true です。メソッドを実行したくない場合は、サブクラスのフック メソッドをオーバーライドし、戻り値を false に変更します。このタイプのフック メソッドは、メソッドの実行を制御し、アルゴリズムに制約を課すことができます。

別のタイプのフック メソッドは、メソッド本体が空である特定のメソッドであり、サブクラスは必要に応じてこれらのフック メソッドをオーバーライドまたは継承できます。抽象メソッドと比較した場合、この種のフック メソッドの利点は、サブクラスが親クラスで定義されたフック メソッドをオーバーライドしない場合、コンパイルは正常に通過できますが、親クラスで宣言された抽象メソッドがカバーされていない場合はコンパイルが成功することです。 、コンパイルでエラーが報告されます。

テンプレート メソッド パターンにおける抽象クラスの一般的なコードは次のとおりです。

abstract class AbstractClass{
    
    
   // 模板方法
   
   // 基本方法——具体方法
   public void primitiveOperation1(){
    
    
      // 实现代码
   }
   
   // 基本方法——抽象方法
   public abstract void primitiveOperation2();
   
      // 基本方法——构子方法
   public abstract void primitiveOperation3(){
    
    
    
   }
}

抽象クラスでは、テンプレート メソッド templateMethod() によってアルゴリズムのフレームワークが定義され、基本メソッドがテンプレート メソッド内で呼び出されて完全なアルゴリズムが実現されます。primitiveOperation1()、primitiveOperation2() などの各基本メソッドはアルゴリズムの一部を実装し、すべてのサブクラスで同じ基本メソッドは、primitiveOperation1() などの親クラスによって実装できます。それ以外の場合は、親クラスで抽象メソッドまたはフック メソッドとして宣言され、異なるサブクラスが primitiveOperation2() や primitiveOperation3() などの異なる実装を提供します。

抽象ステップの実装は、抽象クラスのサブクラスで提供でき、親クラスにすでに実装されている具象メソッドをオーバーライドすることもできます。具象サブクラスの一般的なコードは次のとおりです。

public ConcreteClass extends AbstractClass{
    
    
   public void primitiveOperation2(){
    
    
      // 实现代码
   }
   
      public void primitiveOperation3(){
    
    
      // 实现代码
   }
}

テンプレート メソッド パターンでは、オブジェクト指向ポリモーフィズムにより、サブクラス オブジェクトは実行時に親クラス オブジェクトをオーバーライドし、サブクラスで定義されたメソッドも親クラスで定義されたメソッドをオーバーライドします。したがって、プログラムの実行時には、特定のサブクラスの基本メソッドが親クラスで定義された基本メソッドをオーバーライドし、サブクラスのフック メソッドも親クラスのフック メソッドをオーバーライドするため、フック メソッドが実装されます。サブクラス内のメソッドは親クラスを更新でき、親クラスの動作に対するサブクラスの逆制御を実現するためにメソッドの実行が制約されます。

3. テンプレートメソッドパターンの概要

テンプレートメソッドパターンは、オブジェクト指向の重要な考え方を多く具現化した継承によるコード再利用技術であり、使用頻度の高いパターンです。テンプレート メソッド パターンは、処理プロセスの論理シーケンス (フレームワークの初期化、テストの設定など) が親クラスによって確実に制御されるようにするために、フレームワーク設計 (Spring、JUnit など) で広く使用されています。プロセスなど)。

3.1. 主な利点

  1. テンプレート メソッド パターンは親クラスでアルゴリズムを正式に定義し、そのサブクラスが詳細を実装します。サブクラスが詳細な処理アルゴリズムを実装する場合、アルゴリズム内のステップの実行順序は変更されません。
  2. テンプレート メソッド パターンはコードの再利用手法であり、クラス ライブラリの設計において特に重要です。クラス ライブラリ内のパブリックな動作を抽出し、そのパブリックな動作を親クラスに配置し、そのサブクラスを通じてさまざまな動作を実現します。コードを再利用するために継承を適切に使用することが奨励されます。
  3. Template Method パターンは、反転された制御構造を実装します。サブクラスは、親クラスのフック メソッドをオーバーライドして、特定のステップを実行する必要があるかどうかを判断します。
  4. テンプレート メソッド モードでは、サブクラスを使用して親クラスの基本メソッドをオーバーライドできます。異なるサブクラスは、基本メソッドの異なる実装を提供できます。新しいサブクラスを置き換えたり追加したりするのに非常に便利です。単一責任の原則に準拠しています。そして開閉の原理。

3.2. 主な欠点

テンプレート メソッド パターンの主な欠点は、基本メソッドの異なる実装ごとにサブクラスを提供する必要があることです。親クラスに可変基本メソッドが多すぎると、クラス数が増加し、システムが大きくなり、設計が抽象化されます。この時点では、ブリッジ モードと組み合わせて設計できます。

3.3. 適用可能なシナリオ

  1. いくつかの複雑なアルゴリズムを分割し、アルゴリズムの固定部分をテンプレート メソッドと親クラスの特定のメソッドとして設計し、変更可能な一部の詳細はそのサブクラスによって実装されます。つまり、アルゴリズムの不変部分を一度実装し、変数の動作はサブクラスに任せて実装します。
  2. コードの重複を避けるために、サブクラス間で共通する動作は抽出され、共通の親クラスに集中化される必要があります。
  3. 親クラスに対するサブクラスの逆制御を実現するには、親クラスのアルゴリズムのステップがサブクラスを介して実行されるかどうかを決定する必要があります。

おすすめ

転載: blog.csdn.net/YYBDESHIJIE/article/details/132090517