Java | 早期リターン(ガード節)のメリットと注意点

Java Java
スポンサーリンク

クリーンアーキテクチャに応用する「早期リターン+例外処理+レイヤード設計」

ここまでで「早期リターン」「例外処理」「サービス層とコントローラ層の分離」を見てきました。これをさらに発展させると、クリーンアーキテクチャの考え方に近づきます。


クリーンアーキテクチャの基本

  • エンティティ層 → ビジネスルールの中心(ドメインモデル)
  • ユースケース層 → アプリケーション固有のロジック(サービス層に近い)
  • インターフェース層 → コントローラやAPI、UIなど外部との接点
  • インフラ層 → DBや外部APIなど技術的な依存部分

👉 ポイントは「依存方向が内側に向かう」こと。ビジネスロジックは外部技術に依存しない。


サンプル構成(ユーザープロフィール取得)

エンティティ層(ドメインモデル)

public class UserProfile {
    private String userId;
    private String name;
    private String email;

    // getter/setterなど
}
Java

ユースケース層(業務ロジック)

public class GetUserProfileUseCase {
    private final UserRepository repository;

    public GetUserProfileUseCase(UserRepository repository) {
        this.repository = repository;
    }

    public UserProfile execute(String userId) throws UserNotFoundException {
        UserProfile profile = repository.findById(userId);
        if (profile == null) {
            throw new UserNotFoundException("ユーザーが見つかりません");
        }
        return profile;
    }
}
Java

👉 早期リターンではなく例外を投げることで、ユースケース層は「異常系を外に伝える」役割に徹する。


インターフェース層(コントローラ)

public class UserController {
    private final GetUserProfileUseCase useCase;

    public UserController(GetUserProfileUseCase useCase) {
        this.useCase = useCase;
    }

    public Response getUserProfile(Request req) {
        // --- 早期リターンで入力チェック ---
        if (req == null) return errorResponse(400, "リクエストが空です");
        if (req.getUserId() == null || req.getUserId().isEmpty()) {
            return errorResponse(400, "ユーザーIDが必要です");
        }

        // --- ユースケース呼び出し+例外処理 ---
        try {
            UserProfile profile = useCase.execute(req.getUserId());
            return successResponse(200, "成功", profile);
        } catch (UserNotFoundException e) {
            return errorResponse(404, e.getMessage());
        } catch (Exception e) {
            return errorResponse(500, "予期せぬエラー: " + e.getMessage());
        }
    }

    private Response errorResponse(int code, String message) {
        return new Response(code, message);
    }

    private Response successResponse(int code, String message, Object data) {
        return new Response(code, message, data);
    }
}
Java

インフラ層(リポジトリ)

public class UserRepositoryImpl implements UserRepository {
    private final ExternalApi api;

    public UserRepositoryImpl(ExternalApi api) {
        this.api = api;
    }

    @Override
    public UserProfile findById(String userId) throws IOException {
        return api.fetchProfile(userId);
    }
}
Java

ポイントまとめ

  • 早期リターン: コントローラ層で入力チェックを即終了。
  • 例外処理: ユースケース層やインフラ層で「異常を外に伝える」役割。
  • 責務分離:
    • コントローラ → 入力チェック+レスポンス生成
    • ユースケース → ビジネスロジック
    • リポジトリ → データ取得(外部依存)
  • テスト容易性:
    • ユースケース層はモックリポジトリでユニットテスト可能
    • コントローラ層は統合テストでレスポンス確認可能

✅ こうして「早期リターン+例外処理+レイヤード設計」を組み合わせると、クリーンアーキテクチャの思想に沿った 読みやすく・安全で・テストしやすい設計 が実現できます。

Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました