【Swift UI】Clean Architectureとは?実装サンプルコード
この記事からわかること
- Swift UI/iOSでClean Architectureとは?
index
[open]
\ アプリをリリースしました /
環境
- Xcode:26.0.1
- iOS:26
- Swift:6
- macOS:Tahoe 26.0.1
Clean Architectureとは?
「Clean Architecture(クリーン アーキテクチャ)」とは「Robert C. Martin(通称:Uncle Bob)」さんが自身のブログ記事「The Clean Architecture」を公開したのが始まりのソフトウェアを長期的に保守・拡張しやすくする設計手法の1つです。
クリーンアーキテクチャは以下図のように4層に分割され単一方向の依存のみを許容する構造になっています。外側の層は内側に依存できるが、内側の層は外側に依存することはできません。これはDIP原則(※)に準拠する形になっており、Swiftではプロトコルを活用してこれを実装していきます。
画像引用:クリーンアーキテクチャ(The Clean Architecture翻訳)
※ Dependency Inversion Principle(DIP):依存性逆転の原則・・・「上位クラスは下位クラスに依存してはならず、抽象に依存するべき」
4層は以下のように分割され実装されるべき責務が明確に定義されています。
[内側]
Enterprise Business Rules (Entity, Domain Model)
⇧
Application Business Rules (UseCase, Interactor)
⇧
Interface Adapters (Presenter, RepositoryImpl)
⇧
Frameworks & Drivers (UI, DB, API, etc.)
[外側]
Enterprise Business Rules (Entity, Domain Model)
「Enterprise Business Rules」は最も内側にある層でアプリの本質的なビジネスロジックを表現する層になります。アプリで扱うデータの根幹となるEntity(ドメインモデル)が定義され、外部(DB/API/UI)とは切り離された存在になります。
要するにモデルクラスを定義してあげればOKです。
struct User {
let id: String
let name: String
let age: Int
func isAdult() -> Bool {
return age >= 20
}
}
Application Business Rules (UseCase, Interactor)
「Application Business Rules」は2番目に内側にある層でアプリの処理の流れを定義する層になります。Entityに対する操作の流れだけを司っており、実際の保存・取得などはRepositoryなどに任せます。ここもDB・APIには依存せずあくまでデータを操作できるものが渡されている状態になるのでモックなどに簡単に切り替えられる状態になります。そのためRepositoryなどは直接依存させるのではなくプロトコルで抽象に依存するようにしておきます。
protocol UserRepository {
func fetchUser(id: String) -> User
}
class GetUserProfileUseCase {
private let repository: UserRepository
init(repository: UserRepository) {
self.repository = repository
}
func execute(userId: String) -> User {
return repository.fetchUser(id: userId)
}
}
Interface Adapters (Presenter, RepositoryImpl)
「Interface Adapters」は3番目に内側にある層で内側のユースケースやエンティティと、外側のDB/API/UIとの橋渡しをする層になります。こちらも外部(4つ目の層)をプロトコル経由で受け取り、外部と内部を繋ぎ合わせる役割を実装します。
class UserRepositoryImpl: UserRepository {
private let api: UserApi
init(api: UserApi) {
self.api = api
}
func fetchUser(id: String) -> User {
let response = api.getUser(id: id)
return User(id: response.id, name: response.name, age: response.age)
}
}
Frameworks & Drivers (UI, DB, API, etc.)
「Frameworks & Drivers」は最も外側にある層でUIやDB、API周りの実装を行う層です。UIであればSwift UI / UIKit、DBであればRealm / Core Data、APIならAlamofire / URLSessionのように使われる技術スタックに依存し、変化も大きく起こりやすい部分になります。
class UserApi {
func getUser(id: String) -> UserResponse {
// URLSessionでAPIコール
}
}
struct UserResponse: Decodable {
let id: String
let name: String
let age: Int
}
参考文献[iOS] コードで覚えるクリーンアーキテクチャ 〜VP部分を書いてみよう〜
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。





