0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Architecture】VIPER アーキテクチャ

Posted at

はじめに

iOS 開発の世界では、MVC や MVVM だけでは責務分離が不十分になりがちです。
そこで登場したのが VIPER アーキテクチャ

VIPER は Clean Architecture をベースにした設計思想で、画面単位で役割を明確に分けることで 保守性・テスト容易性 を高めます。


VIPER の構成要素

VIPER は頭文字を取った以下5つの責務に分かれます。

1. View

  • UI を表示し、ユーザー操作を Presenter に伝える
  • 自分でロジックは持たない(受け身)
protocol SampleViewProtocol: AnyObject {
    func showData(_ text: String)
}

class SampleViewController: UIViewController, SampleViewProtocol {
    var presenter: SamplePresenterProtocol!

    override func viewDidLoad() {
        super.viewDidLoad()
        presenter.viewDidLoad()
    }

    func showData(_ text: String) {
        print("表示: \(text)")
    }
}

2. Interactor

  • ビジネスロジック担当(ユースケース)
  • データ取得や処理を行い、結果を Presenter に返す
protocol SampleInteractorProtocol {
    func fetchData()
}

class SampleInteractor: SampleInteractorProtocol {
    weak var presenter: SamplePresenterProtocol?

    func fetchData() {
        let data = "データ取得完了"
        presenter?.didFetchData(data)
    }
}

3. Presenter

  • View と Interactor の仲介役
  • ユーザー操作を受け取り、必要な処理を Interactor に依頼
  • 結果を State に変換して View に渡す
protocol SamplePresenterProtocol: AnyObject {
    func viewDidLoad()
    func didFetchData(_ data: String)
}

class SamplePresenter: SamplePresenterProtocol {
    weak var view: SampleViewProtocol?
    var interactor: SampleInteractorProtocol!
    var router: SampleRouterProtocol!

    func viewDidLoad() {
        interactor.fetchData()
    }

    func didFetchData(_ data: String) {
        view?.showData(data)
    }
}

4. Entity

  • ビジネスルールを表すモデル
  • データそのもの(構造体やクラス)
  • Interactor の中で使われる
struct User {
    let id: Int
    let name: String
}

5. Router

  • 画面遷移やモジュールの組み立て(DI)を担当
  • Presenter が次画面への遷移を依頼する
protocol SampleRouterProtocol {
    static func createModule() -> UIViewController
}

class SampleRouter: SampleRouterProtocol {
    static func createModule() -> UIViewController {
        let view = SampleViewController()
        let presenter = SamplePresenter()
        let interactor = SampleInteractor()
        let router = SampleRouter()

        view.presenter = presenter
        presenter.view = view
        presenter.interactor = interactor
        presenter.router = router
        interactor.presenter = presenter

        return view
    }
}

データフローまとめ

View → Presenter → Interactor → Presenter → View
          ↓
        Router(画面遷移)
          ↓
        Entity(データ)
  • View はユーザー入力を Presenter に渡す
  • Presenter が Interactor を呼び出し、処理結果を受け取る
  • Presenter が View に反映する
  • Router が画面遷移を制御

VIPER のメリット

  • 責務が明確で大規模開発に強い
  • テストしやすい(Interactor, Presenter単体テストが容易)
  • 各層の独立性が高く、再利用性も向上

VIPER のデメリット

  • ファイル数が増える(1画面 = 5ファイル以上)
  • 小規模アプリだとオーバーエンジニアリングになりやすい
  • セットアップ(Router での依存注入)がやや複雑

VIPER と Clean Architecture の関係

  • VIPER = Clean Architecture を iOS に落とし込んだ形
  • UseCase = Interactor
  • Controller = Router
  • Entity = Domain Model
  • Presenter = Application Layer

まとめ

  • VIPER は View / Interactor / Presenter / Entity / Router の5つで構成される
  • Clean Architecture の思想をモバイル開発に適用したもの
  • 大規模開発やチーム開発に向くが、小規模にはやや重い

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?