Refactoring (리펙토링)
[iOS - swift] property 관리 리펙토링 (computed property를 활용한 리펙토링)
jake-kim
2024. 1. 21. 01:18
기초 개념) stored property와 computed property
- 메모리 관점
- stored property - 별도의 메모리 공간 지정 o
- computed property - 별도의 메모리 공간 지정 x
- 사용 관점
- stored property - 값을 저장
- computed property - 접근하는 시점에 stored property들을 가지고 계산하여 반환
stored property를 사용할때 주의할 점
- stored property를 사용하다보면 가장 큰 문제가, 상태 관리를 두 곳 이상에서 하는 경우가 발생
- 상태 관리를 두 곳 이상에서 하다보면 데이터 관리가 맞지 않아 코드 복잡도가 올라가는 현상이 발생
ex) 커스텀 뷰를 만드는데, ButtonWithImageView안에 또 다른 MyButton 커스텀 뷰를 사용하는 경우
- ButtonWithImageView에서 buttonTitleText라는 값을 저장하고 있고, 또 MyButton에서도 titleText를 가지고 있어서 중복으로 값을 관리하고 있는 상태
class ButtonWithImageView: UIView {
private lazy var button = {
let button = MyButton(titleText: buttonTitleText)
// ...
return button
}()
private let imageView = {
// ...
}()
var buttonTitleText: String
init(buttonTitleText: String) {
self.buttonTitleText = buttonTitleText
// ...
}
}
class MyButton: UIButton {
var titleText: String
init(titleText: String) {
self.titleText = titleText
super.init(frame: .zero)
setTitle(titleText, for: .normal)
}
}
- 문제점
- ButtonWithImageView를 사용하는쪽에서 buttonTitleText를 수정하고, 또 이 값이 수정되면 MyButton의 titleText도 수정해줘야하는데 이렇게 되면 상태 관리가 두 곳이므로 두 값을 모두 관리해야해서 휴먼에러가 날 가능성이 높은 코드
- 코드의 복잡도가 높은 코드
Computed property를 활용한 리펙토링
- 상태 관리를 한곳에서 하는것이 가장 베스트
- ButtonWithImageView의 stored property를 제거하고, computed property로 교체하여 상태 관리는 한곳에서만 일어나도록 수정이 필요
- 여기서 의미하는 상태관리는 stored property라고 이해해도 무방
- 수정)
- 아래처럼 buttonTitleText를 computed property로 만들면 해결
- 이제 상태 저장은 항상 필요한 곳인 MyButton쪽에서만 가지고 있기 때문에 코드의 복잡도가 내려가고 상태관리가 단순해지는 코드 관리가 가능
class ButtonWithImageView: UIView {
// var buttonTitleText: String
var buttonTitleText: String {
get { button.titleText }
set { button.titleText = newValue }
}
}