Sobes.tech
Middle+

Ar žinote architektūrą su VIP ciklu?

sobes.tech AI

Atsakymas iš AI

VIP (View, Interactor, Presenter) - tai architektūros šablonas, kuris yra Clean Architecture variacija, taikoma iOS kūrime siekiant atskirti atsakomybę ir pagerinti kodo testavimą. Pagrindas yra vienpusis duomenų srautas tarp komponentų.

VIP komponentai:

  • View: rodo duomenis ir siunčia naudotojo veiksmus (user actions) Interaktoriui. View (UIView, UIViewController arba paprastas protokolas) neturi verslo logikos.
  • Interactor: turi verslo logiką. Gaukia veiksmus iš View, atlieka būtinus veiksmus (pvz., duomenų prieiga, skaičiavimai) ir siunčia rezultatą Presenter. Nėra priklausomas nuo UI.
  • Presenter: gauna duomenis iš Interaktoriaus, formatuoja juos rodymui ir siunčia View. Neturi verslo logikos, atsakingas tik už duomenų pateikimą.

Sąveikos ciklas:

  1. Vartotojas atlieka veiksmą View.
  2. View siunčia "užklausą" (request - struct/enum) Interaktoriui.
  3. Interactor apdoroja užklausą, atlieka verslo logiką ir siunčia "atsakymą" (response - struct/enum) Presenter.
  4. Presenter gauna atsakymą, formatuoja duomenis į "ViewModel" (struct/enum) ir siunčia jį View.
  5. View gauna ViewModel ir atnaujina UI.

Papildomi komponentai (pasirinktinai):

  • Router: valdo navigaciją tarp VIP modulių (scenų). Paprastai kviečiamas iš Interaktoriaus arba Presenter.
  • Worker: Interaktoriaus komponentas, atsakingas už konkrečių užduočių vykdymą (pvz., tinklo užklausos, darbą su Core Data).

Pagrindiniai VIP privalumai:

  • Atsakomybės atskyrimas: aiškus atskyrimas tarp UI, verslo logikos ir pateikimo logikos.
  • Testavimas: lengva testuoti kiekvieną komponentą atskirai, naudojant mock priklausomybes.
  • Priežiūra: pakeitimai viename komponente mažiau veikia kitus.

Pavyzdinė VIP modulio struktūra (UserScene):

UserScene/
├── UserViewController.swift
├── UserInteractor.swift
├── UserPresenter.swift
├── UserRouter.swift
├── UserModels.swift // Užklausų, atsakymų, ViewModel struktūros
├── UserProtocols.swift // Protokolai komponentų tarpusavio komunikacijai

Pavyzdys, kaip įkelti naudotojo duomenis:

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

// UserInteractor
func fetchUserData(request: UserModels.FetchUser.Request) {
    // ... verslo logika duomenų įkėlimui ...
    let response = UserModels.FetchUser.Response(userData: fetchedData)
    presenter?.presentUserData(response: response)
}

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

// UserViewController (įgyvendinimas UserDisplayLogic protokolo)
func displayUserData(viewModel: UserModels.FetchUser.ViewModel) {
    nameLabel.text = viewModel.displayName
    emailLabel.text = viewModel.displayEmail
}