振る舞いパターン
処理の骨組み(テンプレート)を親クラスで定義し、具体的なステップをサブクラスで実装させる。
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)
);
以下の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 - データ同期 【追加要件】 ・実行時間計測 ・ログ出力 ・リトライ機能