Java デザイン パターンのテンプレート メソッド パターンは、動作アルゴリズムのフレームワークを定義し、一部のステップをサブクラスに延期するため、サブクラスはアルゴリズムの構造を変更せずにアルゴリズム内の特定のステップを再定義できます。行動モデル
以下に示すように:
実際、テンプレート メソッドはプログラミングで頻繁に使用されるパターンです。まず例を見てみましょう。ある日、プログラマー A は、整数の配列を与えられて、配列内の数値を小さい値から大きい値に並べ替えて、並べ替えた結果を出力するというタスクを受け取りました。分析すると、この作業はソートと印刷の 2 つの部分に大きく分けられます。印刷機能は実装が簡単ですが、ソートは少し面倒です。しかし、A さんには、最初に印刷機能を完了させて、並べ替え機能を実行する他の人を見つける方法があります。
abstract class AbstractSort { /** * 配列配列を小さい順に並べ替えます * @param array */ protected abstract void showSortResult(int[] array){ this.sort(array); System.out.print("ソート結果: "); for (int i = 0; i < array.length; i++){ System.out.printf("%3s", array[i]);
書き終えた後、A は最近卒業して入社したばかりの同僚 B を見つけて、「メイン ロジックはすでに書きました。残りのロジックは実装できます。」と言いました。そこで、B に AbstractSort クラスを渡し、B に実装を書いてもらいました。 B がそれを引き継いで見てみましょう。コードは次のとおりです。
class ConcreteSort extends AbstractSort { @Override protected void sort(int[] array){ for(int i=0; i<array.length-1; i++){ selectSort(array, i) } } private void selectSort(int[ ] array, int Index) { int MinValue = 32767; // 最小値変数 int IndexMin = 0 // 一時記憶変数 (int i = index; i < array.length; i++) { if (array[i] < MinValue){ // 最小値を求める MinValue = array[i] } } Temp = array[ index] ; // 2 つの値を交換します。 array[index] = array[indexMin] = Temp;
書いたら A に渡すと、A が実行します。
public class Client { public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 }; // デフォルトのデータ配列 public static void main(String[] args){ AbstractSort s = 新しい ConcreteSort(); s.showSortResult(a);
実行結果:
ソート結果:0 1 3 4 5 7 9 10 12 32
うまくいきます。よし、ミッション完了。はい、これはテンプレート メソッド パターンです。社会に出たばかりの卒業生のほとんどは、B と同様の経験をしているはずです。複雑なタスクの場合、社内の優秀な人材がメイン ロジックを作成し、次に一見単純なメソッドを抽象的なメソッドに記述して、他の同僚に開発を任せます。この分業は、明らかなレベルのプログラミング スタッフを抱える企業でよく使用されます。たとえば、プロジェクト チームにアーキテクト、シニア エンジニア、ジュニア エンジニアがいる場合、アーキテクトは通常、多数のインターフェイスと抽象クラスを使用してシステム全体のロジックをつなぎ合わせ、実装コーディングはアーキテクトに引き継がれます。難易度に応じてシニアエンジニアとジュニアエンジニアがそれぞれ担当します。どうでしょうか、テンプレート メソッド パターンを使用したことがありますか?
テンプレート メソッド パターンの構造:
テンプレート メソッド パターンは、抽象クラスと継承構造を介した 1 つ (または複数の) 実装クラスで構成され、抽象クラスのメソッドは次の 3 つのタイプに分類されます。
1. 抽象メソッド: 親クラスで宣言されるだけで実装されません。代わりに、仕様が定義され、そのサブクラスによって実装されます。
2. テンプレート メソッド: 抽象クラスによって宣言および実装されます。一般に、テンプレート メソッドは抽象メソッドを呼び出してメインの論理関数を完成させます。また、ほとんどのテンプレート メソッドは最終型として定義されており、メインの論理関数をサブクラスでオーバーライドできないことを示しています。
3. フックメソッド: 抽象クラスによって宣言および実装されます。ただし、サブクラスは拡張でき、フック メソッドを拡張することでテンプレート メソッドのロジックに影響を与えることができます。
抽象クラスのタスクは論理フレームワークを構築することです。抽象クラスの品質はプログラムの安定性を直接決定するため、通常は経験豊富な担当者によって作成されます。
実装クラスは詳細を実装するために使用されます。抽象クラスのテンプレートメソッドは、クラス拡張のメソッドを実装することでビジネスロジックを完成させます。実装クラスの拡張メソッドが単体テストに合格し、テンプレート メソッドが正しい限り、通常、関数全体に大きなエラーは発生しません。
テンプレート方式の利点と適用可能なシナリオ:
拡張が簡単です。一般に、抽象クラスのテンプレートメソッドは遡及変更しにくい部分であり、抽象メソッドは遡及変更しやすい部分であるため、一般に実装クラスを追加することで機能拡張が容易です。 、これは開閉の原則に沿っています。
メンテナンスが簡単です。テンプレート メソッド パターンの場合、主要なロジックが同じであるため、テンプレート メソッドを使用しないと、同じコードが異なるクラスに分散することになり、メンテナンスが非常に不便になります。 。
より柔軟に。フック メソッドがあるため、サブクラスの実装は親クラスのメイン ロジックの動作にも影響を与える可能性があります。ただし、柔軟性はありますが、サブクラスは親クラスに影響を与えるため、リスコフ置換原則に違反し、プログラムにリスクももたらします。これにより、抽象クラスの設計に対してより高い要件が課されます。
複数のサブクラスに同じメソッドがあり、これらのメソッドのロジックが同じである場合は、テンプレート メソッド パターンの使用を検討できます。このモードは、プログラムの主要なフレームワークは同じだが詳細が異なる状況にも適しています。