작년에 it동아리 활동을 시작하면서 동아리 내 rxswift 스터디에 들어갔습니다.
그 당시에는 mvc도 제대로 몰랐는데, 단지 rxswift가 취업 우대사항에 포함된다는 소리만 듣고
공부를 시작했습니다. (무식하면 용감하다
는 말은 딱 이럴 때 사용하는 말 ..)
이 책으로 함께 스터디를 했었고 스터디를 기록했던 깃허브 주소입니다.
사실 왜 rxswift를 쓰는지 MVVM 은 무엇인지 왜 사용하는지 전혀 이해를 하지 못하고
무작정 공부를 시작했던 터라 요즘 반성을 많이 하고 있습니다 ㅠ_ㅠ
그래서 오늘은 MVVM이 무엇이고 어떤 장점이 있는 구조인지 공부해보고 글을 남겨보겠습니다.
Model / View / Controller로 나누는 패턴입니다.
iOS 에서는 ViewController가 있는데, 규모가 큰 프로젝트에서는 이 VC가 점점 커지고 무거워지면서
Massive ViewController 라는 별명을 가지고 있기도한 패턴입니다.
그래서 우리는 VC의 책임을 덜어줄 다른 패턴을 찾아야 할 필요성이 생겼답니다 !
MVVM 패턴은 Model / View / ViewModel로 이루어져있는 패턴입니다.
여기서 Command Pattern 이란 ?
Command = 명령어
실행될 기능을 추상화, 캡슐화하여 한 클래스에서 여러 기능을 실행할 수 있도록 하는 패턴입니다.
여기서 Data Binding 이란 ?
view와 로직이 분리되어 있어도 한 쪽이 바뀌면 다른 쪽도 업데이트가 이루어 지는 것입니다.
iOS 에서 Data Binding을 하는 방법에는 이런 것들이 있습니다.
이런 방법들에 대해서는 다른 글에서 다뤄보도록 하겠습니다 :)
두 개의 텍스트 필드에 사람의 이름과 나이를 적으면 그 아래 label에 표시되는 예제입니다
struct Person {
var name: String
var age: Int
}
이렇게 Person 모델을 만들어줍니다.
struct PersonViewModel {
typealias Listener = (Person) -> Void
var listener: Listener?
var person: Person {
didSet {
listener?(person)
}
}
...
mutating func bind(listener: Listener?) {
self.listener = listener
}
}
그리고 UITextField를 상속받는 BindingTextField
클래스를 생성해줍니다.
class BindingTextField: UITextField {
var textChanged: (String) -> Void = { _ in }
func bind(callBack: @escaping (String) -> Void) {
textChanged = callBack
addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
}
@objc func textFieldDidChange() {
guard let text = text else { return }
textChanged(text)
}
}
override func viewDidLoad() {
...
personViewModel.bind { [weak self] person in
self?.yearLabel.text = person.name + " " + "\(person.age)세"
}
@IBOutlet weak var nameTextField: BindingTextField! {
didSet {
nameTextField.bind { [weak self] name in
self?.personViewModel.person.name = name
}
}
}
@IBOutlet weak var ageTextField: BindingTextField! {
didSet {
ageTextField.bind { [weak self] ageText in
guard let age = Int(ageText) else { return }
self?.personViewModel.person.age = age
}
}
}
}
이런식으로 구현을 하게되면 View와 ViewModel이 양방향으로 바인딩이 되어있기 때문에
한 쪽에 변화가 생기면 다른 한 쪽도 자동으로 업데이트 되게 됩니다.
위처럼 간단한 예제도 꽤나 긴 코드를 작성해야함을 확인할 수 있습니다.
그래서 저도 처음에는 이 간단한 걸 이렇게 긴 코드로 작성을 해야하는데 이게 왜 좋다는거지?
이런 의문이 들었습니다.
그리고 사실 간단한 프로젝트 수준, 유지보수가 굳이 필요하지 않은 프로젝트라면 MVC는 굉장히 좋은 패턴이라는 생각이 듭니다.
하지만 회사에서 사용하는 모든 코드들은 이후에 새로운 기능이 추가될 확률이 굉장히 높고,
유지보수 및 테스트가 용이해야하기 때문에 많은 회사들이 MVVM 패턴을 채택하고 있는 것 같습니다 :)
그렇기 때문에 MVC가 어느정도 익숙해졌고, 새로운 패턴을 적용해서 개발을 해보고싶다! 하시면
MVVM은 좋은 선택지가 될 것 같네요 ~ ㅎㅎ
저도 이번에 스터디를 하면서 MVVM + Rxswift를 사용해 작은 프로젝트를 시작했습니다.
이 부분도 나중에 글로 작성하게 되면 아래에 링크를 남겨두겠습니다 :)
읽어주셔서 감사합니다 !
참고 링크