[아키텍처] MVVM

Martin Kim·2022년 2월 17일
0

MVVM


MVVM 패턴은 Model, View, View Model로 나뉘어져 있는 아키텍처 디자인 패턴이다.

  1. 사용자가 화면을 통해 Action을 취하면 Command Pattern을 통해 View -> ViewModel로 전달된다.
  2. ViewModel은 Model에게 Data를 요청한다.
  3. Model은 요청받은 Data를 통해 업데이트 된 data를 ViewModel로 전달한다.
  4. ViewModel은 응답받은 데이터를 가공해서 저장한다.
  5. View는 ViewModel과의 Data Binding을 통해서 자동으로 갱신된다.
  • Command Pattern: 실행될 기능을 추상화, 캡슐화하여 한 클래스에서 여러 기능을 실행할 수 있도록 하는 패턴
  • Data Binding: View와 logic이 분리되어 있어도 한 쪽이 바뀌면 다른 쪽도 업데이트가 이루어지는 방식, KVO, Delegation, Functional Reactive Programming, Property Observer 방법들이 있다.

Model

  • 기존 패턴에서의 Model과 동일한 역할을 수행한다.
  • 어플리케이션에서 사용될 실제 데이터에 해당.
  • ViewModel에 의해 가공되고, ViewModel에 가공된 데이터를 전달.
  • ViewModel이 소유하고, ViewModel과의 Data Binding을 통해 ViewModel의 변경사항을 감지하고 UI를 업데이트 한다.
  • 데이터를 어떻게 갖고 있을지만 고려한다.
struct Person { 
  let firstName: String
  let lastName: String
}

View

  • 앱의 UI에 대한 코드를 담고 있는 계층
  • ViewModel로부터 데이터를 가져와 어떻게 배치할지, 특정 상황에 따라 ViewModel의 어떤 메서드를 이용할지에 대해서도 가지고 있다.
class GreetingViewController: UIViewController {
  var viewModel: GreetingViewModelProtocol! {
    didSet {
      self.viewModel.greetingDidChange = { [unowned self] viewModel in
        self.greetingLabel.text = viewModel.greeting
      }
    }
  }

  let showGreetingButton = UIButton()
  let greetingLabel = UILabel()

  override func viewDidLoad() {
    super.viewDidLoad()
    self.showGreetingButton.addTarget(self.viewModel, action: "showGreeting", forControlEvents: .TouchUpInside)
  }
}

// Assembling of MVVM
let model = Person(firstName: "David", lastName: "Blaine")
let viewModel = GreetingViewModel(person: model)
let view = GreetingViewController()
view.viewModel = viewModel

View Model

  • 실제 로직을 담당
  • Model을 소유한다.
  • 유저가 View를 통해 액션을 취해 Model이 업데이트 되어야 할 경우 해당 Model을 업데이트하고 Model로부터 정보를 받아 View를 갱신시킨다.
// 프로토콜
protocol GreetingViewModelProtocol: class {
  var greeting: String? { get }
  var greetingDidChange: ((GreetingViewModelProtocol) -> ())? { get set } 
  init(person: Person)
  func showGreeting()
}

// 뷰모델
class GreetingViewModel: GreetingViewModelProtocol {
  let person: Person
  var greeting: String? {
    didSet {
      self.greetingDidChange?(self)
    }
  }

  var greetingDidChange: ((GreetingViewModelProtocol) -> ())?

  required init(person: Person) {
    self.person = person
  }

  func showGreeting() {
    self.greeting = "Hello" + " " + self.person.firstName + " " + self.person.lastName
  }
}

결론

  • 장점
    • View관련 코드와 비즈니스 로직 관련 코드가 분리 되어 테스트가 용이해진다.
  • 단점
    • View Model 설계가 어려운 편이다.
    • View에 대한 처리가 복잡해질 수록 View Model이 거대해진다

참고: https://velog.io/@sso0022/iOS-MVC-%EC%99%80-MVVM
https://gwangyonglee.tistory.com/49

profile
학생입니다

0개의 댓글