본문은 야곰 아카데미 커리어 스타터 캠프를 통해 학습한 내용을 회고한 글입니다.
Protocol Oriented Programming
STEP01
main과 Chargeable 소스파일을 만든 후 commit해준다. main.swift:
typealias WattPerHour = Int
typealias Watt = Int
Chargeable.swift:
protocol Chargeable {
var maximumWattPerHour: WattPerHour { get set }
func convert(chargeableWattPerHour: WattPerHour) -> WattPerHour
}
그리고 STEP01을 commit 해준다. commit 해주기 이전에 POPExercise.xcodeproj파일이 자꾸 commit 되려고 해서 fork에서 이 부분 역시 ignore 처리 해주었다:
STEP02
feat-MacBook, feat-charger라는 이름의 브랜치를 각각 생성해준다:
요구사항에는 Charger를 구조체로 구현하라고 되어있었지만, enum으로 한 번 구현해봤다. Charger 열거형의 코드:
enum Charger: Chargeable, Portable {
case appleWatchCharger
case iphoneFastCharger
case ipadCharger
case macBookCharger
case macBookFastCharger
var name: String {
switch self {
case .appleWatchCharger:
return "5Wh 애플워치 충전기"
case .iphoneFastCharger:
return "18Wh 아이폰 고속 충전기"
case .ipadCharger:
return "30Wh 아이패드 충전기"
case .macBookCharger:
return "96Wh 맥북 충전기"
case .macBookFastCharger:
return "106Wh 맥북 충전기"
}
}
var maximumWattPerHour: WattPerHour {
switch self {
case .appleWatchCharger:
return 5
case .iphoneFastCharger:
return 18
case .ipadCharger:
return 30
case .macBookCharger:
return 96
case .macBookFastCharger:
return 106
}
}
func convert(chargeableWattPerHour: WattPerHour) -> WattPerHour {
return min(chargeableWattPerHour, maximumWattPerHour)
}
}
MacBook 구조체의 코드:
import Foundation
struct MacBook: Portable {
let name: String
let maximumWattPerHour: WattPerHour
var currentBattery: Watt {
didSet {
print("현재 저장된 배터리는 \(currentBattery)W입니다.")
}
}
let maximumBattery: Watt
init(name: String, maximumWattPerHour: Int, currentBattery: Int, maximumBattery: Int = 100) {
self.name = name
self.maximumWattPerHour = maximumWattPerHour
self.currentBattery = currentBattery
self.maximumBattery = maximumBattery
}
mutating func chargeBattery(charger: Chargeable) {
print("\(name)을/를 충전합니다.")
print("충전 중...")
let chargeTime = calculateChargingTime(charger: charger)
let formattedChargeTime = String(format: "%.2f", chargeTime)
print("기존 저장된 배터리는 \(currentBattery)W였으며, \(charger.name)을 사용하여 완충까지 \(formattedChargeTime)시간 걸렸습니다.")
currentBattery = maximumBattery
}
func calculateChargingTime(charger: Chargeable) -> Double {
let batteryToBeCharged = maximumBattery - currentBattery
let chargeTime = Double(batteryToBeCharged) / Double(charger.convert(chargeableWattPerHour: maximumWattPerHour))
return chargeTime
}
}
각각의 코드를 xcodeproj 파일 없이 stage에 올린 후 각각 commit해준다. 그리고 둘 다 commit이 되면 메인이 될 브랜치에 merge해준다.
step03
가방에 물건을 넣는 프로토콜을 채택해주면 된다
Portable프로토콜의 코드:
protocol Portable {
var name: String { get }
}
struct Bag {
private var items: [Portable] = [] {
didSet {
print("가방에 \(items.last?.name ?? "물건")을/를 넣었습니다.")
}
}
mutating func put(item: Portable...) {
item.forEach { item in
items.append(item)
}
}
}
완성된 코드가 돌아가는 모습이다:
POP의 매커니즘
구체적인 타입이 아닌 추상화된 프로토콜을 통해 내부 구현을 숨긴다는 것이 이번 주차 학습의 핵심이었다고 볼 수 있다.
func calculateChargingTime(charger: Chargeable) -> Double {
...
}
위의 코드처럼 매개변수로 프로토콜을 받는 것이 그 사례라고 볼 수 있다.
'YAGOM CAREER STARTER' 카테고리의 다른 글
[CODE STARTER 복습] 20230317: week01 (0) | 2023.03.17 |
---|---|
[TIL] 20230314: wait()/notify(queue:) (0) | 2023.03.14 |
[TIL] 20230309: Sync/Async/Blocking/Non-Blocking (0) | 2023.03.09 |
[TIL] 20230307: 동기/비동기/직렬/동시성, DispatchQueue (0) | 2023.03.07 |
[TIL] 20230303: 프로토콜로 id 지정하기 (0) | 2023.03.04 |