← 一覧に戻る

Template Method

振る舞いパターン

処理の骨組み(テンプレート)を親クラスで定義し、具体的なステップをサブクラスで実装させる。

目次
  1. クラス図
  2. シーケンス図
  3. アクティビティ図
  4. 使いどころ
  5. コード例
  6. AIプロンプト例
  7. 注意点
  8. 関連パターン

クラス図

シーケンス図

アクティビティ図

使いどころ

コード例

抽象クラス(テンプレート)

public abstract class DataProcessor {
    
    // テンプレートメソッド(処理の骨組み)
    public final void process() {
        openConnection();
        List<String> data = fetchData();
        List<String> transformed = transformData(data);
        saveData(transformed);
        closeConnection();
        sendNotification();
    }

    // 共通処理(オーバーライド不可)
    private void openConnection() {
        System.out.println("接続を開始");
    }

    private void closeConnection() {
        System.out.println("接続を終了");
    }

    // サブクラスで実装必須
    protected abstract List<String> fetchData();
    protected abstract List<String> transformData(List<String> data);
    protected abstract void saveData(List<String> data);

    // フック(任意でオーバーライド)
    protected void sendNotification() {
        // デフォルトは何もしない
    }
}

具体的なサブクラス

// CSVからDBへの取り込み
public class CsvToDbProcessor extends DataProcessor {
    private final String csvPath;
    private final String tableName;

    public CsvToDbProcessor(String csvPath, String tableName) {
        this.csvPath = csvPath;
        this.tableName = tableName;
    }

    @Override
    protected List<String> fetchData() {
        System.out.println("CSVファイル読み込み: " + csvPath);
        return Files.readAllLines(Path.of(csvPath));
    }

    @Override
    protected List<String> transformData(List<String> data) {
        System.out.println("データ変換(ヘッダー除去、バリデーション)");
        return data.stream()
            .skip(1)  // ヘッダー行をスキップ
            .filter(line -> !line.isEmpty())
            .collect(Collectors.toList());
    }

    @Override
    protected void saveData(List<String> data) {
        System.out.println("DBテーブル " + tableName + " に" + data.size() + "件保存");
    }

    @Override
    protected void sendNotification() {
        System.out.println("Slack通知: インポート完了");
    }
}

// APIからファイルへの出力
public class ApiToFileProcessor extends DataProcessor {
    private final String apiUrl;
    private final String outputPath;

    public ApiToFileProcessor(String apiUrl, String outputPath) {
        this.apiUrl = apiUrl;
        this.outputPath = outputPath;
    }

    @Override
    protected List<String> fetchData() {
        System.out.println("API呼び出し: " + apiUrl);
        // API呼び出し処理
        return callApi();
    }

    @Override
    protected List<String> transformData(List<String> data) {
        System.out.println("JSON → CSV変換");
        return convertToCsv(data);
    }

    @Override
    protected void saveData(List<String> data) {
        System.out.println("ファイル出力: " + outputPath);
        Files.write(Path.of(outputPath), data);
    }
    // sendNotificationはデフォルト(何もしない)を使用
}

使用例

// CSVインポート
DataProcessor csvProcessor = new CsvToDbProcessor("data.csv", "users");
csvProcessor.process();
// 出力:
// 接続を開始
// CSVファイル読み込み: data.csv
// データ変換(ヘッダー除去、バリデーション)
// DBテーブル users に100件保存
// 接続を終了
// Slack通知: インポート完了

// APIエクスポート
DataProcessor apiProcessor = new ApiToFileProcessor("https://api.example.com/users", "output.csv");
apiProcessor.process();

ラムダを使った軽量版

public class SimpleProcessor {
    
    public void process(
        Supplier<List<String>> fetcher,
        Function<List<String>, List<String>> transformer,
        Consumer<List<String>> saver
    ) {
        System.out.println("処理開始");
        List<String> data = fetcher.get();
        List<String> transformed = transformer.apply(data);
        saver.accept(transformed);
        System.out.println("処理完了");
    }
}

// 使用例
new SimpleProcessor().process(
    () -> Files.readAllLines(Path.of("input.txt")),
    lines -> lines.stream().map(String::toUpperCase).toList(),
    lines -> Files.write(Path.of("output.txt"), lines)
);

AIプロンプト例

カスタマイズ用プロンプト

以下のTemplate Methodパターンを作成してください。

【用途】
帳票生成処理

【テンプレートの流れ】
1. initDocument() - ドキュメント初期化
2. renderHeader() - ヘッダー出力【抽象】
3. renderBody() - 本文出力【抽象】
4. renderFooter() - フッター出力【抽象】
5. finalizeDocument() - 最終処理
6. afterRender() - 後処理【フック】

【サブクラス】
1. InvoiceReport - 請求書
2. SalesReport - 売上レポート
3. InventoryReport - 在庫一覧

【共通処理】
・ページ番号付与
・出力日時記録
・PDF保存

バッチ処理用プロンプト

バッチ処理用のTemplate Methodパターンを作成してください。

【テンプレートの流れ】
1. initialize() - 初期化
2. validate() - 入力検証【抽象】
3. preProcess() - 前処理【フック】
4. execute() - メイン処理【抽象】
5. postProcess() - 後処理【フック】
6. handleError() - エラーハンドリング【フック】
7. cleanup() - 後片付け

【サブクラス例】
・DailyAggregationBatch - 日次集計
・MonthlyClosingBatch - 月次締め処理
・DataSyncBatch - データ同期

【追加要件】
・実行時間計測
・ログ出力
・リトライ機能

注意点

← 一覧に戻る