はじめに
ソフトウェア設計において「境界をどこまで引くか?」は大きなテーマです。
Clean Architecture では、完全に分離された境界(Fully Developed Boundaries) と 境界なし(No Boundaries) の間に、部分的な境界(Partial Boundaries) という選択肢が提示されています。
本記事では、この Partial Boundaries の考え方と、実践例について整理します。
境界の3つのスタイル
1. Fully Developed Boundaries(完全な境界)
- インターフェースを介して依存を逆転
- 実装と利用側が完全に切り離される
- メリット:交換容易、テスト容易、高い柔軟性
- デメリット:抽象化コスト・コード量が増える
// Domain 側
interface UserRepository {
fun findById(id: String): User
}
// Infrastructure 側
class SqlUserRepository : UserRepository {
override fun findById(id: String): User { ... }
}
2. No Boundaries(境界なし)
- 直接呼び出す
- シンプルだが、結合度が高くなる
class UserService {
private val repo = SqlUserRepository()
fun getUser(id: String): User = repo.findById(id)
}
3. Partial Boundaries(部分的な境界)
- 抽象化を部分的に導入
- 境界のコストを最小化しつつ、将来の変更余地を残す
- 「まず軽く仕切っておく」イメージ
// 抽象化を用意するが、実装は1つだけ
interface WeatherService {
fun getTodayWeather(): Weather
}
class OpenWeatherService : WeatherService {
override fun getTodayWeather(): Weather { ... }
}
// 利用側
class WeatherPresenter(private val service: WeatherService) {
fun show() = println(service.getTodayWeather())
}
Partial Boundaries の適用シーン
-
小規模プロジェクト
- 完全な境界を作るコストは高すぎるため、部分的な境界で十分
-
将来的な変更の可能性が高い箇所
- 例:DB や外部 API
- 最初はラッパーを用意し、必要になれば本格的に分離
-
モジュール化の過渡期
- 最初は Partial → 後から Fully Developed へ進化
まとめ
Partial Boundaries は、「完全に分ける」か「まったく分けない」かの二択ではなく、その中間で柔軟に線を引く手法 です。
- コストと柔軟性のバランスをとれる
- 必要に応じて進化可能
- 小規模開発や将来の拡張を見据えた現実的な選択肢
Clean Architecture の実践において、部分的な境界をどう引くか は設計者の腕の見せどころと言えるでしょう。