1定義
テンプレートメソッドパターンは、親クラスのアルゴリズムフレームワークを定義し、特定のステップをサブクラスに遅延させて実装できるため、サブクラスは、アルゴリズムフレームワークを変更せずに、アルゴリズムの特定のステップを再定義できます。
2構造図
主な役割は以下のとおりです。
抽象クラス/抽象テンプレート(抽象クラス)
アルゴリズムの概要とスケルトンを提供する抽象テンプレートクラス。これは、テンプレートメソッドといくつかの基本的なメソッドで構成されています。これらのメソッドの定義は次のとおりです。
①テンプレートメソッド:アルゴリズムのスケルトンを定義し、それに含まれる基本メソッドを特定の順序で呼び出します。
②基本的な方法:以下のタイプを含むアルゴリズム全体のステップです。
- 抽象メソッド:抽象クラスで宣言され、具象サブクラスによって実装されます。
- 具体的なメソッド:抽象クラスに実装されており、具体的なサブクラスで継承またはオーバーライドできます。
- フックメソッド:抽象クラスに実装されています。これには、判断のための論理メソッドや、サブクラスで書き直す必要のある空のメソッドが含まれます。
具体的なサブクラス/具体的な実装(具体的なクラス)
具象実装クラスは、抽象クラスで定義された抽象メソッドとフックメソッドを実装します。これらは、トップレベルロジックの構成ステップです。
3長所と短所
3.1利点
1.不変部分をカプセル化し、可変部分を拡張します。不変部分と見なされるアルゴリズムを親クラスにカプセル化し、サブクラスからの継承によって可変部分アルゴリズムを実装して、サブクラスが拡張し続けることができるようにします。
2.親クラスのコードの共通部分を抽出します。これは、コードの再利用に便利です。
3.一部のメソッドはサブクラスによって実装されるため、サブクラスは、オープンクローズの原則に準拠する拡張によって対応する関数を追加できます。
3.2デメリット
1.異なる実装ごとにサブクラスを定義する必要があります。これにより、クラスの数が増え、システムが大きくなり、設計がより抽象的なものになり、間接的にシステム実装の複雑さが増します。
2.親クラスの抽象メソッドは子クラスによって実装され、子クラスの実行結果は親クラスの結果に影響を与えるため、逆制御構造になり、コードの読み取りが困難になります。 。
3.継承関係自体の欠点により、親クラスが新しい抽象メソッドを追加する場合は、すべてのサブクラスを再度変更する必要があります。
4コード例
たとえば、放課後は学生が食べに行きます。みんなが食堂に歩いて行き、さまざまな料理を作ります。食べた後は、さまざまな行動があります。クラスメートAは寮に戻って寝、クラスメートBは戻ってきます。勉強を続けるために教室に。
4.1抽象クラスMyDinner
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-23 10:52
**/
public abstract class MyDinner {
public void templateMethod(){
printStudentIdentity();
/**
* 下课一起去食堂吃饭,大家走去食堂方式一样,去食堂打的饭菜不一样,吃完饭回的地方不一样,有人回宿舍,有人回教室
*/
walk();
haveMeal();
goAfterMeal();
}
/**
* 打印学生身份
*/
public abstract void printStudentIdentity();
public void walk(){
System.out.println("到点了,走去吃晚饭");
}
/**
* 打饭,具体打什么菜
*/
public abstract void haveMeal();
/**
* 吃完饭后去哪儿
*/
public abstract void goAfterMeal();
}
4.2 学生A StudentA
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-23 11:01
**/
public class StudentA extends MyDinner{
@Override
public void printStudentIdentity(){
System.out.println("我是学生A");
}
@Override
public void haveMeal() {
System.out.println("今天心情不错,来一个麻辣香锅,重麻重辣");
}
@Override
public void goAfterMeal() {
System.out.println("吃饱喝足,回宿舍再睡一觉,简直美吱吱");
}
}
4.3学生BStudentB
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-23 11:03
**/
public class StudentB extends MyDinner{
@Override
public void printStudentIdentity(){
System.out.println("我是学生B");
}
@Override
public void haveMeal() {
System.out.println("考试没考好,就吃个最便宜的拉面吧");
}
@Override
public void goAfterMeal() {
System.out.println("接着去自习室吧,我需要好好复习了");
}
}
4.4主な機能MainClass
/**
* @program: design-pattern-learning
* @author: zgr
* @create: 2021-09-23 10:51
**/
public class MainClass {
public static void main(String[] args) {
MyDinner studentA = new StudentA();
studentA.templateMethod();
System.out.println("**********************************");
MyDinner studentB = new StudentB();
studentB.templateMethod();
}
}
4.5実行結果
5テンプレートメソッドパターンのアプリケーションシナリオ
1.アルゴリズムの全体的な手順は非常に固定されていますが、個々の部分が可変である場合、この時点でテンプレートメソッドパターンを使用して、サブクラスが実装する簡単に変化する部分を抽象化できます。
2.複数のサブクラスに共通の動作がある場合、コードの重複を避けるために、それらを抽出して共通の親クラスに集中させることができます。まず、既存のコードの違いを特定し、それらを新しい操作に分離します。最後に、別のコードを、これらの新しい操作を呼び出すテンプレートメソッドに置き換えます。
3.サブクラスの拡張を制御する必要がある場合、テンプレートメソッドは特定のポイントでのみフック操作を呼び出すため、拡張はこれらのポイントでのみ許可されます。
6引用
1.「Dahuaデザインパターン」
2.テンプレートメソッドパターンの詳細な説明(テンプレートメソッドデザインパターン)