MVP 패턴 실습해보기

suojae·2023년 11월 25일
0

[iOS] 아키텍쳐

목록 보기
5/11

MVP 패턴 기본구조




#1 심플한 MVP 예제


#1 Diagram

+----------------+         +----------------+          +---------------+
|                |  fetch  |                |  update  |               |
|     Model      | ------> |   Presenter    | <------  |     View      |
| (UserProfile)  |   ^     | (UserDetails)  |    |     | (ProfileUI)   |
+----------------+   |     +----------------+    |     +---------------+
                     |             ^             |
                     |             |             |
                     +-------------+-------------+
                        saveProfile()

#1 View


import UIKit

//MARK: - View
protocol ProfileViewProtocol: AnyObject {
    func displayUpdateResult(success: Bool)
}

class ProfileViewController: UIViewController, ProfileViewProtocol {
    var presenter: ProfilePresenterProtocol!

    // UI elements like textfields

    func onUpdateButtonTapped() {
        let profile = UserProfile(
            name: "nameTextField.text",
            email: "emailTextField.text"
        )
        
        presenter.updateProfile(profile)
    }

    func displayUpdateResult(success: Bool) {
        // Show success or error message
    }
}

#1 Presenter


import Foundation

//MARK: - Presenter
protocol ProfilePresenterProtocol {
    func updateProfile(_ profile: UserProfile)
}

class ProfilePresenter: ProfilePresenterProtocol {
    weak var view: ProfileViewProtocol?
    var model: ProfileModelProtocol

    init(view: ProfileViewProtocol, model: ProfileModelProtocol) {
        self.view = view
        self.model = model
    }

    func updateProfile(_ profile: UserProfile) {
        let success = model.updateProfile(profile)
        view?.displayUpdateResult(success: success)
    }
}

#1 Model


import Foundation

//MARK: - Model
struct UserProfile {
    var name: String
    var email: String
}

protocol ProfileModelProtocol {
    func updateProfile(_ profile: UserProfile) -> Bool
}

class ProfileModel: ProfileModelProtocol {
    func updateProfile(_ profile: UserProfile) -> Bool {
        // Update and return the result
    }
}


#2 옵저버 패턴을 이용해 View가 Model을 감시하고 있는 경우 (프리젠테이션 경유)


#2 Diagram

            +--------------------+
            |                    |
            |   UserProfileView  |
            | (UserProfileVC)    |
            |                    |
            +---------^----------+
                      |
                      | updates UI
                      |
         +------------+-----------+    +-------------------+
         |                        |    |                   |
         |  UserProfilePresenter  +--->+  UserProfileModel |
         |                        |    |                   |
         +------------+-----------+    +---------^---------+
                      ^                           |
                      | observes changes          |
                      |                           | notifies changes
                      |                           |
                      +---------------------------+

#2 View


import UIKit

//MARK: - View
protocol UserProfileViewProtocol: AnyObject {
    func displayUserProfile(_ userProfile: UserProfile)
}

class UserProfileViewController: UIViewController, UserProfileViewProtocol {
    var presenter: UserProfilePresenter!

    // UI elements like labels, text fields

    func displayUserProfile(_ userProfile: UserProfile) {
        // Update the UI elements with userProfile details
    }

    // Actions for UI elements to update the model
    @IBAction func nameChanged(_ sender: UITextField) {
        presenter.updateName(sender.text ?? "")
    }

    @IBAction func emailChanged(_ sender: UITextField) {
        presenter.updateEmail(sender.text ?? "")
    }
}

#2 Model


import Foundation

//MARK: - Model
class UserProfile {
    var name: String {
        didSet {
            notifyObservers()
        }
    }
    var email: String {
        didSet {
            notifyObservers()
        }
    }

    private var observers = [UserProfileObserver]()

    init(name: String, email: String) {
        self.name = name
        self.email = email
    }

    func addObserver(_ observer: UserProfileObserver) {
        observers.append(observer)
    }

    private func notifyObservers() {
        observers.forEach { $0.userProfileDidChange(self) }
    }
}

protocol UserProfileObserver {
    func userProfileDidChange(_ userProfile: UserProfile)
}

#2 Presenter

import Foundation

//MARK: - Presenter
class UserProfilePresenter {
    private let model: UserProfile
    private weak var view: UserProfileViewProtocol?

    init(model: UserProfile, view: UserProfileViewProtocol) {
        self.model = model
        self.view = view
        model.addObserver(self)
    }

    func updateName(_ name: String) {
        model.name = name
    }

    func updateEmail(_ email: String) {
        model.email = email
    }
}

extension UserProfilePresenter: UserProfileObserver {
    func userProfileDidChange(_ userProfile: UserProfile) {
        view?.displayUserProfile(userProfile)
    }
}
profile
Hi 👋🏻 I'm an iOS Developer who loves to read🤓

0개의 댓글