---
# System prepended metadata

title: Protocol Oriented Programming
tags: [toyo]

---


# Protocol Oriented Programming
### 참여자
 - vetto
 - harry
 - 리지
 - 송준

### 진행자
- vetto

### 진행일시
- 2023.03.11
 
### 학습키워드
- Type
- Protocol
- Git, Branch

## 👨‍🔬 실험 1: 기능을 위해 필요한 Protocol 타입을 설계하기

- Charger가 채택하기 위한 프로토콜 타입을 생성
   - maximumWattPerHour: WattPerHour(최대 허용 와트시) 를 갖는 프로퍼티
   - convert(chargeableWattPerHour: WattPerHour) → WattPerHour 메서드 : 충전기와 기기의 허용 와트시를 검사해서, 기기의 허용 와트시가 더 낮다면, 기기에 맞추어 와트시를 낮추어 반환

```Swift
import Foundation

typealias WattPerHour = Int
typealias Watt = Int

protocol Chargeable {
    var maximumWattPerHour: WattPerHour { get }
    
    func convert(chargeableWattPerHour: WattPerHour) -> WattPerHour
}
```

## 👨‍🔬 실험 2: Branch를 나누어 구현한 뒤 합치기
- feat-MacBook 브랜치로 이동해 맥북을 구현합니다.
- 맥북은 프로퍼티로 다음을 갖습니다.
    - 기기의 허용 충전 와트시
    - 현재 저장된 배터리용량 (와트시)
    - 최대 배터리 용량 (100와트시)
- 맥북은 메서드로 다음을 갖습니다.
    - chargeBattery(charger: Chargeable) : 충전기를 활용해 배터리를 완전히 충전한 뒤 충전에 걸린 시간을 print 합니다.
- feat-Charger 브랜치로 이동해 충전기를 구현합니다.
- 충전기는 실험 1 프로토콜을 채택 및 구현합니다.
- 다양한 종류의 maximumWattPerHour 를 가진 충전기 인스턴스를 생성합니다.
    - 5Wh 애플워치 충전기, 18Wh 아이폰 고속 충전기, 30Wh 아이패드 충전기, 96Wh 맥북 충전기, 106Wh 맥북 충전기,
- 두 브랜치를 하나의 Main 브랜치로 Merge합니다.
- 맥북 인스턴스를 하나 생성한 후 다양한 충전기로 각각 충전했을 때 완전히 충전될때까지 몇 시간이 걸리는지 확인해보세요!

```swift
var macbook = MacBook(currentBattery: 20)
let watchCharger: Charger = .init(maximumWattPerHour: 5)
let fastCharger: Charger = .init(maximumWattPerHour: 18)
let iPadCharger: Charger = .init(maximumWattPerHour: 30)
let macBookCharger: Charger = .init(maximumWattPerHour: 96)
let macBookCharger2: Charger = .init(maximumWattPerHour: 106)

macbook.chargeBattery(charger: watchCharger)
macbook.chargeBattery(charger: fastCharger)
macbook.chargeBattery(charger: iPadCharger)
macbook.chargeBattery(charger: macBookCharger)
macbook.chargeBattery(charger: macBookCharger2)
```

결과
![](https://i.imgur.com/lNhoQXR.png)
* macbook의 허용 충전 와트시를 임의로 65로 고정하고 출력을 진행하였다.

### git branch merge 시 문제 해결

1. `.gitattributes` 파일 생성
``` bash
vi .gitattributes // .gitattributes 파일 생성
*.pbxproj binary merge=union // .gitattributes 파일에 입력 후 저장
```

<br>

2. `커밋`
``` bash
git add .
git commit -m "*.pbxproj Avoid Merge Conflict"
git push origin main

```
- pbxproj 파일에는 프로젝트 파일의 reference가 있다.
- 각 브랜치 별로 동일한 위치에 파일을 생성하게 되면 reference가 겹치게 되어 conflict가 발생하는 것을 확인했다.
- pbxproj 파일은 사실 텍스트 파일이지만 이를 merge 할때 바이너리 파일처럼 취급해 conflict을 해결할 수 있다.

3. 폴더 구조 미리 생성하기
- 폴더 및 파일 구조를 미리 구상하여 생성 해놓고 브랜치를 파고 들어가서 비어있는 파일을 들어가 코드를 작성하고 머지한다.

## 👨‍🔬 실험 3: Protocol을 통해 가방에 넣기
```swift
struct MacBook: Portable {}
struct Charger: Chargeable, Portable {}

struct Bag {
    private(set) var items: [Portable] = []

    mutating func put(item: Portable) {
        items.append(item)
    }
}
```
```swift
let appleWatchCharger = Charger(maximumWattPerHour: 5)
let myMacBook = MacBook(currentBattery: 20)

var gucciBag = Bag()

gucciBag.put(item: appleWatchCharger)
gucciBag.put(item: myMacBook)
```

Portable 프로토콜을 준수하고 있는 타입들을 받을 수 있는 배열을 선언해준뒤 MacBook 인스턴스와 Charger 인스턴스가 Bag.items 배열 안에 추가 될 수 있게 MacBook, Charger타입에 Portable 프로토콜을 준수하게 코드를 작성하였다.

###### tags: `toyo`