🧅

オニオンアーキテクチャについて

に公開

はじめに

過去に関わったDDDでのプロジェクトで、オニオンアーキテクチャを採用していて個人的にすごくわかりやすいアーキテクチャだったので備忘も兼ねて記事にしようと思った。

個人開発でも、わかりやすいので良く採用するアーキテクチャでもある。

オニオンアーキテクチャとは

アプリケーションの構造を設計する手法の一つ。

  • 関心ごとの分離をして変更に耐えられる
    • 分離しているので、階層ごとに分けてテストをしやすい。
  • 責務を分離させているため
    • どこに何を実装すべきかわかりやすい
    • バグの原因の切り分けがしやすい

参考

この動画がわかりやすかった
https://www.youtube.com/watch?v=80NeuPXs2J0

概要図

実際のフォルダ構成を考えてみる

ベースはこんな感じで作って、必要に応じて新たな責務を持つ階層を作る。

src/main/java/com/example/carshop/
│
├── domain/                      【第1層:ドメイン層(中心)】
│   ├── model/                   # ビジネスエンティティ
│   │   ├── Car.java            # 車エンティティ
│   │   ├── Price.java          # 価格値オブジェクト
│   │   └── CarId.java          # 車ID値オブジェクト
│   │
│   ├── repository/              # リポジトリインターフェース
│   │   └── ICarRepository.java # 永続化の抽象
│   │
│   └── service/                 # ドメインサービス
│       └── CarPriceCalculator.java  # 価格計算ロジック
│
├── usecase/                     【第2層:ユースケース層】
│   └──  car/                     # 車関連のユースケース
│        ├── RegisterCar.java    # 車登録
│        ├── UpdateCarPrice.java # 価格更新
│        ├── SearchCar.java      # 車検索
│        └── DeleteCar.java      # 車削除
│   
│   
│
├── infrastructure/              【第3層:インフラストラクチャ層】
│   ├── persistence/             # データベース実装
│       ├── repository/
│       │   └── CarRepositoryImpl.java  # ICarRepositoryの実装
│       ├── entity/
│           └── CarEntity.java          # JPA/DBエンティテ
│   
│
└── presentation/                【第4層:プレゼンテーション層(最外層)】
    ├── controller/              # REST コントローラー
    │   └── CarController.java  # APIエンドポイント
    │
    ├── request/                 # APIリクエスト
    │   ├── RegisterCarRequest.java
    │   └── UpdatePriceRequest.java
    │
    ├── response/                # APIレスポンス
    │   ├── CarResponse.java
    │   └── ErrorResponse.java
    │
    └── exception/               # 例外ハンドリング
        └── GlobalExceptionHandler.java

オニオンと呼ばれる理由

先ほどの概要図を丸く図示し直すと、玉ねぎみたいに丸いから。
(個人的には丸くしないほうがわかりやすい、、)

最後に

クリーンアーキテクチャなど、他にもソフトウェアのアーキテクチャは多々あるが、
個人的にはオニオンが直感的に一番理解しやすく難易度が低いと感じたので今後も使っていきたいと思う。

ただ個人やチームがよりわかりやすい方、またアプリ設計に合わせて選定することが大切であると感じる。

Discussion