デザインパターン テンプレート メソッドパターン 注記
説明する
学習デザインパターン・テンプレート・メソッド・パターンの書き方を記録します。使用される JDK バージョンはバージョン 1.8 です。
テンプレートメソッド
目的: 一部のステップをサブクラスに延期しながら、操作でアルゴリズムのスケルトンを定義します。テンプレート メソッドを使用すると、アルゴリズムの構造を変更せずに、サブクラスがアルゴリズムの特定のステップを再定義できます。
構造:
で:
- AbstractClass (抽象クラス) は抽象プリミティブ操作を定義し、特定のサブクラスはアルゴリズムの各ステップを実装するためにそれらを再定義します: テンプレート メソッドを実装し、アルゴリズムのスケルトンを定義します。テンプレート メソッドはプリミティブ操作を呼び出すだけでなく、定義操作も呼び出します。 AbstractClass または他のオブジェクト内。
- ConcreteClass (具象クラス) は、特定のサブクラスに関連するアルゴリズムのステップを完了するための基本操作を実装します。
適用性:
- アルゴリズムの不変部分を一度実装し、変数の動作をサブクラスに任せます。
- コードの重複を避けるために、各サブクラスの共通の動作を抽出して共通の親クラスに集約する必要があります。
- サブクラス拡張を制御します。テンプレート メソッドは、特定のポイントで「フック」操作 (デフォルトの動作。サブクラスは必要に応じて再定義および拡張できます) を呼び出すように設計されており、これらのポイントでの拡張のみが許可されます。
使用するシーン:
- アルゴリズムの全体的なステップは非常に固定されていますが、個々の部分が可変である場合、テンプレート メソッド パターンを使用して、サブクラスによる実装のために容易に可変の部分を抽象化できます。
- サブクラスによる親クラスの逆制御を実現するには、親クラスのアルゴリズムで特定のステップを実行するかどうかをサブクラスを使用して決定する必要があります。
目次
テンプレートメソッドパターンのクラス図の例
この UML クラス図を使用して、テンプレート メソッド パターンの例を実装します。
抽象クラス
package com.example.deesign_patterns.template_method;
//抽象类(定义模板方法和基本方法)
public abstract class AbstractClass {
//模板方法定义,烹饪方法
public final void cookProcess(){
pourOil();
heatOil();
pourVegetable();
pourSauce();
fry();
}
//第一步:倒油是一样的,所以直接实现
public void pourOil(){
System.out.println("倒油");
}
//第二步:热油是一样的,所以直接实现
public void heatOil(){
System.out.println("热油");
}
//第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
public abstract void pourVegetable();
//第四步:倒调位料是不一样的
public abstract void pourSauce();
//第五步:翻炒是一样的,所以直接实现
public void fry(){
System.out.println("炒啊炒啊炒到熟啊");
}
}
キャベツ
package com.example.deesign_patterns.template_method;
//包菜类
public class ConcreteClassCabbage extends AbstractClass{
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是包菜");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是辣椒");
}
}
キャベツ
package com.example.deesign_patterns.template_method;
//菜心类
public class ConcreteClassHeart extends AbstractClass{
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是菜心");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是蒜蓉");
}
}
テストクラス
package com.example.deesign_patterns.template_method;
//测试类
public class Client {
public static void main(String[] args) {
//炒包菜,创建包菜对象
ConcreteClassCabbage cabbage=new ConcreteClassCabbage();
//炒菜心,创建菜心对象
//ConcreteClassHeart cabbage=new ConcreteClassHeart();
//调用烹饪方法
cabbage.cookProcess();
}
}
利点:
- コードの再利用性を向上させます。コードの同じ部分を抽象親クラスに配置し、異なるコードを異なるサブクラスに配置します。
- リバース制御を実現します。親クラスがそのサブクラスを呼び出す操作を通じて、またサブクラスの特定の実装を通じてさまざまな動作を拡張することによって、逆制御が実現され、開始および終了の原則に準拠します。
欠点:
- 異なる実装ごとにサブクラスを定義する必要があるため、クラスの数が増加し、システムが大きくなり、設計がより抽象化されます。
- 親クラスの抽象メソッドはサブクラスによって実装されるため、サブクラスの実行結果が親クラスの結果に影響を及ぼし、制御結果が逆転してコードの読み取りが困難になります。