설계할 때 자주 쓰이는 템플릿. 선배들의 삽질기록.
코드의 모양새
Design Patterns(1994) by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
디자인 패턴의 의미
단, 적절히 잘 사용하자
디자인 패턴을 수단으로 사용해야지 목적으로 사용하면 주객전도되는 상황이 생길 수도 있다.
*주어진 패턴을 상황에 맞게 변경을 해서 사용해야 하는데 디자인 패턴에 집착하게 되면 유연하게 패턴을 적용 및 변경을 못하게 된다. 따라서 100퍼센트 지킬 필요는 없지만 명확하게 알아두면 쓸 일이 많다.
Architecture: 큰 그림, 소프트웨어의 전반적인 큰 그림
ex) 서양 건축물 양식, MVC architecture
Design Pattern: 이 Architecture 안에서 세세한 부분을 해결하는 해결방식
ex) 서양 건축물 안의 불편한 설계부분을 수정해서 현재에 맞게 적용하는 것.
MVC (Model-View-Controller) Architecture
무슨 기준으로 나누었나?
기준을 나누는 요소들은 무엇인가?
Model, View, 그리고 Controller
Model은 데이터를 다루는 것을 정의 하는 것
사용자에게 보이는 것은 전부 view라는 영역에 속하는 instance
*view와 view controller는 다르다!!
"저장 프로퍼티뿐 아니라 추가적으로 클래스, 구조체, 열거형은 *계산된 프로퍼티를 선언할 수 있습니다. 이 계산된 프로퍼티는 실제 값을 저장하고 있는 것이 아니라
getter
와optional
한setter
를 제공해 값을 탐색하고 간접적으로 다른 프로퍼티 값을 설정할 수 있는 방법을 제공합니다."출처: 프로퍼티 (Properties) - The Swift Language Guide (한국어) (gitbook.io)
메소드를 통해 인스턴스 값을 접근하려면 두 개의 메소드를를 구현해야 한다. 해당 인스턴스에 접근해 주는 메서드와 해당 인스턴스를 설정 해 주는 메소드 이렇게 두가지를 구현해 주어야 하는데 이 메서드가 분산 구현되기 때문에 코드의 가독성이 저하될 가능성이 있기 때문에 이런경우 연산프로퍼티를 쓰는 것이 더 간편하고 직관적이게 코드를 만들어준다.
구조체 예제는 책과 여러 블로그에 많이 나와 있기에 클래스 내부의 값을 특정한 상태에 다른 값을 연산하는 접근자(getter)와 설정자(setter) 역할을 하는 메소드를 활용하여 코드를 작성 해 봤다.
내 가상의 지갑상황을 가지고 코드문을 작성해 봤다.
역시 부모님께 잘해야겠다는 생각이 들었다.
import Foundation
class MyWallet {
var money: Int
var card: String
init(won: Int, checkCard: String) {
self.money = won
self.card = checkCard
}
func supportFromParents() -> MyWallet {
return MyWallet(won: 200000, checkCard: "신한카드")
}
func putMoneyInMyWallet(_ support: MyWallet) {
money += support.money
card = support.card
}
}
var myProperty: MyWallet = MyWallet(won: 200, checkCard: "신용 카드가 없습니다.")
print("지금 저는 \(myProperty.card) 그리고 제 지갑에는 \(myProperty.money)원 밖에 없습니다. ")
print("제가 불쌍한지 부모님이 \(myProperty.supportFromParents().card) 그리고 \(myProperty.supportFromParents().money)원을 지원 해 주셨습니다.")
myProperty.putMoneyInMyWallet(myProperty.supportFromParents())
print("그래서 제 총 자산은 \(myProperty.money)원이 되었고 이제 \(myProperty.card)도 있습니다.")
// 지금 저는 신용 카드가 없습니다. 그리고 제 지갑에는 200원 밖에 없습니다.
// 제가 불쌍한지 부모님이 신한카드 그리고 200000원을 지원 해 주셨습니다.
// 그래서 제 총 자산은 200200원이 되었고 이제 신한카드도 있습니다.
해당 메소드를 연산프로퍼티와 비교해 보자.
class MyWallet {
var money: Int
var card: String
init(won: Int, checkCard: String) {
self.money = won
self.card = checkCard
}
var supportFromParents: MyWallet { //연산 프로퍼티
// 접근자
get {
return MyWallet(won: 200000, checkCard: "신한카드")
}
// 설정자
set (support) {
money += support.money
card = support.card
}
// 매개 변수 이름을 생략한 설정자는 아래와 같이 설정할 수 있다.
set {
money += newValue.money
card = newValue.card
}
}
}
// My Tung Tung empty Wallet
var myProperty: MyWallet = MyWallet(won: 200, checkCard: "신용 카드가 없습니다.")
// GET financial supoprt from parents, thank God
print("지금 저는 \(myProperty.card) 그리고 제 지갑에는 \(myProperty.money)원 밖에 없습니다. ")
print("제가 불쌍한지 부모님이 \(myProperty.supportFromParents.card) 그리고 \(myProperty.supportFromParents.money)원을 지원 해 주셨습니다.")
// SET changes in my Pocket
myProperty = myProperty.supportFromParents
print("그래서 제 총 자산은 \(myProperty.money)원이 되었고 이제 \(myProperty.card)도 있습니다.")
// 그래서 제 총 자산은 200000원이 되었고 이제 신한카드도 있습니다.
get
부분 같은경우 변화를 주는 값이라는 느낌이 오고
set
부분은 변화가 적용된 값이라고 느낌을 받았다.
메소드를 활용할 때 접근자와 설정자를 호출할 때 다른 두 개의 메소드를 활용해야 했었는데 연산프로퍼티를 활용할 경우 하나의 변수를 활용하여 접근하기에 훨씬 수월하다는 느낌을 받았다.
더 나아가 연산프로퍼티를 읽기 전용으로 구현하려면 get
메소드만 사용하면 된다.
class iOSCamperInformation {
var gitHubIdAndAge: [String: Int]
init(gitHubIdAndAge: [String: Int]) {
self.gitHubIdAndAge = gitHubIdAndAge
}
// 아래와 같이 하면 return 값이 iOSCamperInformation type이다
var james: iOSCamperInformation { //연산 프로퍼티
// 접근자
get {
return iOSCamperInformation(gitHubIdAndAge: ["James": 27])
}
var yagom: iOSCamperInformation {
get {
return iOSCamperInformation(gitHubIdAndAge: ["yagom": 22])
}
}
}
}
// create camperMembers instance
var camperMembers: IOSCamper = IOSCamper(gitHubIdAndAge: ["camper": 13])
// GET james
camperMembers = camperMembers.james
print(camperMembers.gitHubIdAndAge) // ["James", 27]
// SET이 설정되어 있지 않기 때문에 error!!
camperMembers = camperMembers.gitHubIdAndAge
TIL 예문을 작성하기 전까지는 굳이 메소드를 두고 왜 연산프로퍼티를 쓰는지 의문이 들었지만 쓰다보니 정말로 간편하다는 것을 깨달았다. 앞으로 자주 애용해야겠다.
참고문헌:
스위프트 프로그래밍 3판 - 야곰
내 가상의 지갑사정
야곰책의 예문과 인터넷에 올라온 예제 코드를 보면 솔직히 머리에도 잘 안들어오고 배운다는 느낌을 안 받았다. 그래서 오늘 연산프로퍼티를 몇 번이고 읽어봤지만 매우 헷갈렸다.
그런 상황에서 내 상상력을 활용하여 나만의 코드 예제를 만들고 해당 문법을 활용하니 머리속에도 더 잘 들어오고 내것으로 어느정도 흡수했다는 느낌을 받았다. 단순히 복사 붙여넣기로 다른사람의 예제를 TIL에 적기보다 앞으로도 이렇게 자주 나만의 코드예제를 만들어서 책과 인터넷에서 배운 내용을 능동적으로 학습해야겠다고 다짐했다.