🔥 TIL-Day 78設計モード-テンプレートメソッドテンプレートメソッド


テンプレートメソッドとは何かを知る前に、テンプレートメソッドが必要な場合を理解します.
2つのレベルTestATestBがあります.
2つのクラスには、0.5秒を必要とする任意の操作を実行する方法(logic)がある.logicメソッドの実行時間を測定する必要がある要件は以下の通りである.
@Slf4j
public class WithoutTemplateMethodTest {

    public class TestA {
        public void logic() throws InterruptedException {           
            log.info("start");
            // 실행시간 측정시작
            long start = System.currentTimeMillis();
            
            // 비즈니스 로직
            log.info("TestA logic1 processing ...");
            Thread.sleep(500);

            // 실행시간 로그출력
            long end = System.currentTimeMillis();
            long spendTime = end - start;
            log.info("end, time = {}", spendTime);
        }
    }

    public class TestB {
        public void logic() throws InterruptedException {
            // 실행시간 측정시작
            log.info("start");
            long start = System.currentTimeMillis();

            // 비즈니스 로직
            log.info("TestB logic processing ...");
            Thread.sleep(500);
            
            // 실행시간 로그출력
            long end = System.currentTimeMillis();
            long spendTime = end - start;
            log.info("end, time = {}", spendTime);
        }
    }
}
2つのlogicメソッドでは、ビジネスロジックを実行するコードは2行しかありません.
ビジネスロジックに関係のない実行時間を測定するコードの量は、より多くなります.また、運転時間測定部は完全に重複している.このようなビジネスロジックに関係のない汎用的な追加機能は、コードが長くなり、重複します.
これらのビジネスロジックに関係のない付加機能(記録、実行時間測定など...)テンプレートメソッドは、分離の解決策として使用できます.

📌 テンプレートメソッドの適用


テンプレートメソッドは、その名の通り、あるテンプレートを提供することです.
ここで、テンプレートには不変の付加機能が含まれており、テンプレートコードの任意の場所でビジネスロジックを実行する方法を呼び出すだけでよい.
継承を使用してテンプレートメソッドモードが適用されます.
テンプレートの役割を果たす抽象クラスを定義し、サブクラスでビジネスロジックに上書きする抽象メソッドを提供します.
汎用付加機能に対応するexecuteの部分では、サブクラスから上書きを担当するトラフィックロジックを呼び出すcallメソッドが実現される.
@Slf4j
public abstract class AbstractTemplate {

    public void execute() {
        log.info("start");
        long start = System.currentTimeMillis();

        call();

        long end = System.currentTimeMillis();
        long spendTime = end - start;
        log.info("end, time = {}", spendTime);
    }

    protected abstract void call();
}
現在、実行時間を測定する方法を有するクラスは、AbstractTemplateを継承し、call方法をカバーすることができる.
@Slf4j
public class SubClass1 extends AbstractTemplate {

    @Override
    protected void call() {
        log.info("logic1 processing ...");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


@Slf4j
public class SubClass2 extends AbstractTemplate{

    @Override
    protected void call() {
        log.info("logic2 processing ...");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
定義された2つのクラスのインスタンスを作成し、テストを実行します.
public class TemplateMethodTest {

    @Test
    void test() {
        AbstractTemplate subClass1 = new SubClass1();
        subClass1.execute();

        SubClass2 subClass2 = new SubClass2();
        subClass2.execute();
    }
}
親タイプを使用してインスタンスを作成(アップグレード)し、メソッドを呼び出しすぎると、サブクラスのメソッドが多すぎます.
テスト結果は、テンプレートメソッドが適用されていない場合と全く同じです.

📌 リファレンス


インフラ-スプリングコア原理高級編(金英漢)