Java | 「for-each+例外処理+ログ」のテンプレートをクラス構造で整理(実務クラス設計例)

Java Java
スポンサーリンク

ここでは「拡張for文(for-each)+例外処理+ログ出力」を組み合わせた、実務的なクラス構造テンプレートを示します。
実際のプロジェクトでよく使う「データ処理+エラー対応+ログ管理」の構成をベースにしています。


実務テンプレート:for-each+例外+ログ(Java)

import java.util.List;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

// =============================================
// 業務処理全体をまとめるクラス
// =============================================
public class DataProcessor {
    private static final Logger logger = Logger.getLogger(DataProcessor.class.getName());
    private final DataRepository repository;
    private final DataService service;

    // 依存オブジェクトを注入
    public DataProcessor(DataRepository repository, DataService service) {
        this.repository = repository;
        this.service = service;
    }

    // メインの処理メソッド
    public void execute() {
        logger.info("=== データ処理を開始します ===");

        List<String> items = repository.fetchAll();

        for (String item : items) {
            try {
                logger.info("処理対象: " + item);
                service.process(item);
            } catch (InvalidDataException e) {
                logger.warning("無効なデータをスキップしました: " + item + " (" + e.getMessage() + ")");
            } catch (Exception e) {
                logger.log(Level.SEVERE, "予期せぬエラーが発生しました: " + item, e);
            }
        }

        logger.info("=== データ処理が完了しました ===");
    }

    // 動作テスト用 main
    public static void main(String[] args) {
        DataRepository repo = new DataRepository();
        DataService service = new DataService();
        new DataProcessor(repo, service).execute();
    }
}

// =============================================
// データ取得クラス(DBやAPIアクセス想定)
// =============================================
class DataRepository {
    public List<String> fetchAll() {
        // 実務ではDBやAPIからデータを取得する処理になる
        List<String> list = new ArrayList<>();
        list.add("Alice");
        list.add("Bob");
        list.add("");
        list.add("Charlie");
        return list;
    }
}

// =============================================
// 実際の業務ロジックを担うクラス
// =============================================
class DataService {
    public void process(String name) throws InvalidDataException {
        if (name == null || name.isEmpty()) {
            throw new InvalidDataException("名前が空です");
        }
        // 実際の処理(例:API送信・登録など)
        System.out.println("ユーザー処理中: " + name);
    }
}

// =============================================
// カスタム例外クラス(ビジネスロジック用)
// =============================================
class InvalidDataException extends Exception {
    public InvalidDataException(String message) {
        super(message);
    }
}
Java

クラス構造の考え方

役割クラス主な責務
データ管理DataRepositoryデータを取得する(DB・ファイル・APIなど)
業務処理DataService各データのビジネスロジック(検証・登録など)
統括制御DataProcessorfor-eachで全件処理+例外ハンドリング+ログ管理
例外定義InvalidDataException業務エラーを明確に分離する

ベストプラクティス要点

項目解説
try-catchをループ内に書く各要素でエラーが出ても他の処理を続けられる。
カスタム例外クラス「想定内の業務エラー(無効データ)」を InvalidDataException として区別。
ログレベルを使い分けるINFO(正常)/WARNING(軽微なエラー)/SEVERE(重大な障害)。
再スローしない設計業務エラーはログだけ記録して処理を続行。致命的なエラーなら throw も可能。
依存オブジェクトを注入(DI)テストやメンテナンスをしやすくするため、内部で new しない構成。

✅ 応用ポイント(実務向け改良例)

  • Logger → 実務では SLF4J + Logback に置き換えるとよい。
  • List<String> → 実務では List<Customer> のようにドメインオブジェクトを扱う。
  • エラー件数をカウント・CSV出力・リトライ制御を追加するなども可能。
タイトルとURLをコピーしました