Sobes.tech
Middle+

Да ли знате архитектуру са VIP циклусом?

sobes.tech АИ

Одговор од АИ

VIP (View, Interactor, Presenter) - to je arhitektonski obrazac koji predstavlja varijantu Clean Architecture, primenjenu u iOS razvoju za razdvajanje odgovornosti i poboljšanje testabilnosti koda. Osnova je jednostruki tok podataka između komponenti.

VIP komponente:

  • View: Prikazuje podatke i šalje akcije korisnika (user actions) Interaktoru. View (UIView, UIViewController ili jednostavno protokol) ne sadrži poslovnu logiku.
  • Interactor: Sadrži poslovnu logiku. Prima akcije od View, izvršava potrebne operacije (npr. pristup podacima, izvođenje kalkulacija) i šalje rezultat Presenter-u. Ne zavisi od UI.
  • Presenter: Prima podatke od Interaktora, formatira ih za prikaz i šalje View-u. Ne sadrži poslovnu logiku, odgovoran je samo za prikaz podataka.

Ciklus interakcije:

  1. Korisnik izvršava akciju u View.
  2. View šalje "zahtev" (request - struct/enum) Interaktoru.
  3. Interactor obrađuje zahtev, izvršava poslovnu logiku i šalje "odgovor" (response - struct/enum) Presenter-u.
  4. Presenter prima odgovor, formatira podatke u "ViewModel" (struct/enum) i šalje ga View.
  5. View prima ViewModel i ažurira UI.

Dodatne komponente (opciono):

  • Router: Upravlja navigacijom između VIP modula (scena). Obično se poziva od Interaktora ili Presentera.
  • Worker: Komponent Interaktora, zadužen za izvršenje specifičnih zadataka (npr. mrežni zahtevi, rad sa Core Data).

Glavne prednosti VIP:

  • Razdvajanje odgovornosti: Jasno razdvajanje između UI, poslovne logike i logike prikaza.
  • Testabilnost: Lako testirati svaki komponent odvojeno, koristeći mock zavisnosti.
  • Održavanje: Promene u jednom komponentu manje utiču na ostale.

Primer strukture foldera za VIP modul (UserScene):

UserScene/
├── UserViewController.swift
├── UserInteractor.swift
├── UserPresenter.swift
├── UserRouter.swift
├── UserModels.swift // Strukture za Request, Response, ViewModel
├── UserProtocols.swift // Protokoli za komunikaciju između komponenti

Primer interakcije (učitavanje podataka korisnika):

// U UserViewController
func viewDidLoad() {
    super.viewDidLoad()
    interactor?.fetchUserData(request: UserModels.FetchUser.Request())
}

// U UserInteractor
func fetchUserData(request: UserModels.FetchUser.Request) {
    // ... poslovna logika za učitavanje podataka ...
    let response = UserModels.FetchUser.Response(userData: fetchedData)
    presenter?.presentUserData(response: response)
}

// U UserPresenter
func presentUserData(response: UserModels.FetchUser.Response) {
    let viewModel = UserModels.FetchUser.ViewModel(
        displayName: response.userData.name,
        displayEmail: response.userData.email
    )
    viewController?.displayUserData(viewModel: viewModel)
}

// U UserViewController (implementacija protokola UserDisplayLogic)
func displayUserData(viewModel: UserModels.FetchUser.ViewModel) {
    nameLabel.text = viewModel.displayName
    emailLabel.text = viewModel.displayEmail
}