MVC Class Diagram
- Model: 앱 데이터를 가지도 있다. struct 나 간단한 class 로 구성된다.
- Views: 시각적인 요소들과 화면을 담당한다. UIView 의 Subclass 이다.
- Controllers: model 과 view를 통합시킨다.
Controller 는 model 과 view의 string properties를 가져 직접 access가 가능하다. 또한 하나 이상의 view와 model 을 가질 수 있다.
반대로 model 과 view 들은 controller 에 대한 string reference 가 없어 retain cylce의 문제가 발생할 수 있다.
대신에 model 은 property observing 을 통해 controller 와 통신한다. view 는 IBActions를 통해 controller 와 통신한다.
이렇게 되면 Model 과 View를 여러 controller 에서 재사용할 수 있게 해준다.
*view 는 weak refernece 를 delegate 를 통해 가지고 있다.
예를들어 UITableView 는 delegate 와 datasource 를 통해 weark reference를 가진다.
Controller 의 경우 MVC에서 재사용 하기 힘들다.
언제 MVC를 사용할까
iOS app개발 초기에 사용하는것이 좋다.
다른 패턴들도 추후에 필요할 것이지만 필요한 그때그때 차용하는 게 좋고 시작은 MVC로 하는걸 추천
MVC 예제 코드
import UIKit
//Model
public struct Address {
public var street : String
public var city : String
public var state : String
public var zipCode : String
}
//View
public final class AddressView : UIView {
@IBOutlet public var streetTextField : UITextField!
@IBOutlet public var cityTextField : UITextField!
@IBOutlet public var stateTextField : UITextField!
@IBOutlet public var zipCodeTextField : UITextField!
}
//Controller
public final class AddressViewController : UIViewController {
//Holding Strong referecne with Model and View
public var address : Address? {
didSet {
//Model -> Controleller
updateViewFromAddress()
}
}
public var addressView : AddressView! {
guard isViewLoaded else {return nil}
return (view as! AddressView)
}
}
public override func viewDidLoad() {
super.viewDidLoad()
updateViewFromAddress()
}
//Controller -> Model
private func updateViewFromAddress(){
guard let addressView = addressView,
let address = address else {return}
addressView.streetTextField.text = address.street
addressView.cityTextField.text = address.city
addressView.stateTextField.text = address.state
addressView.zipCodeTextField.text = address.zipCode
}
//View -> Controller
@IBAction public func updateAddressFromView(_ sender : AnyObject) {
guard let street = addressView.streetTextField.text,
street.count > 0,
let city = addressView.cityTextField.text,
city.count > 0,
let state = addressView.stateTextField.text,
state.count > 0
let zipCode = addressView.zipCodeTextField.text,
zipCode.count > 0 else{
return
}
address = Address(street: street, city: city, state: state, zipCode: zipCode)
}
MVC를 사용하며 주의할 점
Model, View, Controller 에 속하지 않는 Object가 있을 수 있다. 그래서 많은 logic 이 controller 에 집중될 수 밖에 없다.
결국 controller의 코드량이 많아져 Massive View Controller 가 될 수 도 있다.
한가지 알게된 점
나는 처음 iOS앱을 만들때 IBOutlet 을 Controller 에 binding 했고 따로 UIView class 를 만들지 않았다. 이 방식이 MVC 이고 View 는 그럼 storyboard 의 xib를 말하는 거였구나 생각했었는데 UIView class 를 따로 만들고 controller 에서
public var addressView : AddressView! {
guard isViewLoaded else {return nil}
return (view as! AddressView)
}
이런식으로 view를 불러서 사용하는 지는 몰랐다.
생각해 보면 View 는 UIView 의 subclass 라고 했는데 왜 그렇게 생각했지 싶다.
'iOS > Design Pattern' 카테고리의 다른 글
Design Pattern - Singleton Pattern (0) | 2020.08.09 |
---|---|
Design Pattern - Strategy Pattern (0) | 2020.08.07 |
Design Pattern - Delegation Pattern (0) | 2020.08.06 |
Design Pattern - Class Diagram (0) | 2020.07.14 |
Design Pattern - Introduction (0) | 2020.07.14 |
댓글