Template Method

振る舞いパターン

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

クラス図

シーケンス図

アクティビティ図

使いどころ

コード例

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

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 - データ同期

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

注意点