[iOS] App Development

[iOS] 디자인패턴 : MVVM

ddgoori 2021. 12. 3. 17:17

디자인패턴 왜 필요한가?

- 객체지향 설계에서 변화를 최소한 줄여줄 수 있는 기술을 제공한다.

- 새로운 기능이 추가되고 성능을 최적화할 시에 버그 등, 의도치 않은 결과를 불러일으킬 확률을 최소화 한다.

- 유지보수가 용이한 소프트웨어를 만들 수 있다. (다른 사람이 작성한 코드를 더 쉽게 이해할 수 있다.)

- 공용어의 힘을 사용할 수 있다.

“자, 나는 broadcast라는 클래스를 만들었어. 이 클래스는 모든 객체가 이 클래스를 예의 주시하고 있지. 언제라도 새로운 데이터가 이 클래스로부터 만들어지면 모든 리스너가 이 메시지를 받아. 가장 멋진 점은 리스너가 broadcast에 어 때이든지 참가할 수 있고 빠질 수 있다는 거야.”
 
아니면,
 
“자, 난 broadcast 클래스를 옵저버 패턴으로 만들었어”
 
첫 번쨰 기술에서는 여러분은 broadcast 클래스가 정말 뭘 하는지 이해하는데 많은 생각을 해야만 했습니다. 두번째는 여러분이 이미 이 문장을 보자마자 알차릴 수 있죠. 이게 바로 디자인 패턴을 사용하는 것의 힘이기도 합니다. 만약 여러분이 패턴의 용어로 의사소통을 한다면, 다른 개발자들도 즉시 여러분이 무슨말을 하고싶어 하는지 캐치할 수 있을 것입니다.

원문 : 
5 reasons to finally learn design patterns

 

MVVM패턴?

Model: 데이터보유, 일반적으로 구조체 또는 단순 클래스

View/ViewController: 버튼, 레이블, 이미지, 텍스트 필드 등 시각적 요소와 컨트롤을 화면에 표시

ViewModel:  모델 정보를 뷰에 표시할 수 있는 값으로 변환하고 모델과 뷰 사이의 다리 역할을 한다.

 

이미지 출처:  https://ichi.pro/ko/swift-mich-mvvm-dijain-paeteon-eul-sayonghan-logeu-in-hwamyeon-guhyeon-74723834678771

 

 

테이블 뷰 예제를 통해서 패턴을 이해해보자.

 

 

기타

  • Main.storyboard에서 네비게이션컨트롤러를 embed하면, 해당 뷰컨에 네비게이션 바 제목이 생긴다, 해당 영역을 선택하고 우측에서 Navigation Item - Title에서 네비게이션 제목을 설정할 수 있다.

 

아래에서 Person은 Model이고

테이블뷰를 그려주는 Controller가 있다.(소스코드 생략)

 

ViewModel은 무엇인가? intermedaite between the model and view

=> 가끔 모델이 진짜 커질 경우가 있는데, 예를 들면 페이스북에선 Person의 property가 굉장히 많아진다.

birthdate: Date?, middleName: String?, address: String?, gender: Gender등 

enum Gender {

   vase male, female, unspecified

}

 

문제는 view가 이런 모델 데이터 전부를 원하는게 아니다.

정말 뷰가 원하는 정보를 얻고 싶을 때가 있다.

ViewController에서 tableView와 tableViewCell 분리 PersonsFollowingTableViewCell: UITableViewCell로

Models라는 곳에 Models.swfit로 모델 분리

 

View 뷰

PersonsFollowingTableViewCell.Swift
PersonsFollowingTableViewCell.Swift 에 그려주는 소스코드 추가
PersonsFollowingTableViewCell.Swift 에 contentView.addSubView로 UI 그려주기
PersonsFollowingTableViewCell.Swift의 func layoutSubview에 UI 그려주기

아래 소스코드에서 ViewModel 생성한 것 사용

 

PersonsFollowingTableViewCell.Swift의 configure에 viewmodel의 데이터 넣어주기

 

PersonsFollowingTableViewCell.Swift 버튼 누를때마다 버튼 리셋하기

맨 위에 tap 액션을 위해 델리게이트 설정

델리게이트 설정 후 configure 메소드 하위에 self.viewModel = viewModel을 해줘야 함

reatin the viewModel onto the cell 유지할 수 있게.

 

delegate로 Delegate 받고

viewModel에 viewModel 받고 아래와 같이 선언 button에 액션을 받기 위해

뷰가 우리가 탭하는걸 모르게 한다.

override init function 하위에 버튼 addtarget으로 액션추가

 

 

ViewModel 뷰모델

(View이름+ViewModel.swfit)

 

PersonalFollowingTableViewCellViewModel {

}

아래 ViewModel에 정의한 것이 cell을 보여주는데(render out) 요한 기본적인 요소들이다.

PersonalFollowingTableViewCellViewModel.swift

 

Person model로 부터  데이터를 받아오기 위해서 아래처럼 소스코드를 추가한다.

PersonalFollowingTableViewCellViewModel.swift

 

 

 

ViewController 뷰컨트롤러

 

뷰컨트롤러에서 모델에서 뷰모델을 구성한다.

PersonalFollowingTableViewCellViewModel.swift 에서는 해당 셀과 관련한 모델만 있다.

위의 뷰 모델에서 Model.swift에 있는 Person 모델에서 몇가지 속성을 가져다 사용하고 싶다.

 

cell은 테이블뷰셀, 테이블뷰셀에 configure를 만들어 놓았음. Person model을 넣음 

위 코드에 cell.delegate = self 추가 하고 아래 extension 추가

 

 

 

 

 

Model 모델

Models.swift

 

 

struct Person {
   let name: String
}

// array of Person object
private var models = [Person]()

// viewDidLoad에서 호출 : set up models and put them into arrays
private func configureModels() {
  let names = [
      "dahae", "taeri", "suzy", "hyegyo"
  ]
  
  for name in names {
  	models.append(Person(name: name))
  }
}

 

정리하면

PersonalFollowingTableViewCellViewModel은 Model에서 가져온 정보로 init 시키고

PersonalFollowingTableViewCell에서 ViewModel의 데이터를 변경해준다.

 

 

 


 

쉬운 예제 Ver

 

MVC

Done by

 

(View)Controller  - Handlig Taps, Transforming model data(하지만 베스트는 아님)

Networking - Loading Data

Models

Views

 

MVVM

 

사용 이유

Sick of giant view controllers?

Not sure where to put your app’s business logic?

Wanting to write tests but can’t for the life of you get started?

 

Lucky for you, the Model-View-ViewModel pattern is the answer you’ve been looking for! In this session you’ll get hands on experience organizing your code into easy-to-understand testable components using MVVM.

 

https://www.youtube.com/watch?v=sWx8TtRBOfk 

 

 

ViewModels

Models

Views

 

MVVM에도 위의 그림과 같이 ViewController가 있지만, 메인 포커스가 아니다.

viewmodels flpww on to the models

=> viewmodel을 model과 view의 중간자 역할을 하게 만든다

=> viewmodel이 model data를 view reperesentation으로 변환하는 작업을 한다.

 

viewcontroller를 slim down하는게 목적!

 

기존 MVC패턴에서 보면

단지 제품 상세 화면을 보여주기 위해서 뷰컨에서 데이터 변경하는 소스코드가 꽤나 많다.

=> 이것을 뷰모델에서 하는게 낫다.

 

ViewModel 폴더를 만들고 ViewModel.swift 파일을 만든다. 

=> 여기에는 product instance, initializer가 있어야한다.

*assistant 켜기 옵션 누른채로 해당 파일 누르면 양쪽으로 켜짐

 

예제코드)

 

뷰컨에 있는 것을 1 to 1으로 매핑하며 변경한다.

오른쪽 뷰컨에 있는 것을 => 뷰모델로 1:1로 변경

 

그리고 뷰컨에 있는 Model을 ViewModel로 변경한다.

그리고 뷰컨트롤러에는 ViewModel에 있는 property나 메소드를 사용한다.

 

뷰컨이 아래와 같이 심플해졌다.

로직을 다 지우고 viewmodel에 있는 것을 가져와서 보여주기만 하면 된다.

Key: creating view model to handle the data transformation!

 

 

모델이 있으면, 그 모델을 가져와서 모델의 데이터를 변경하고 계산하는 로직은 ViewModel에 넣고, ViewController에서는 ViewModel을 가져와서 사용. ViewController에서는 계산된 것 데이터 UI 에 뿌려주기만 한다.

 

모든 뷰컨의 로직을 뷰모델에 옮겨도 되고, 일부만 옮겨도 된다. 다만 뷰모델이 너무 커지지 않게 하는 것이 중요함.

 

 

 

 

 

 

내용 출처:

 

ttps://ichi.pro/ko/swift-mich-mvvm-dijain-paeteon-eul-sayonghan-logeu-in-hwamyeon-guhyeon-74723834678771

 

Swift 및 MVVM 디자인 패턴을 사용한 로그인 화면 구현

Microsoft 설계자 인 Ken Cooper와 Ted Peters가 특별히 사용자 인터페이스의 이벤트 기반 프로그래밍을 단순화하기 위해 발명 한 소프트웨어 엔지니어 MVVM 디자인 패턴으로 잘 알려진이 기사에서 발표

ichi.pro

 

https://www.youtube.com/watch?v=qzXJckVxE4w 

https://www.youtube.com/watch?v=bFoLlwuzAtk