정의된 프로콜을 보고도 감이 잘 안오는 분들을 위한 글




디자인 패턴을 공부하다 보니 protocol까지 흘러들어갔습니다. 문법책에있는 내용은 정말 빌드 시 에러가 나지 않을 만큼만 이라서 이 프로토콜을 정리 할 필요가 있다고 생각되었습니다.

protocol 정의

protocol Student {
    var name: String { get }
    var grade: Int? { get }
}

struct Leeo: Student {
    let name: String
    let grade: Int?
}

let leeo = Leeo(name: "hyunho", grade: nil)
print(leeo)

위와 같이 protocol이라는 키워드를 사용해서 프로토콜을 정의 해줍니다. 그리고 정의한 프로토콜을 채택해서 구현 해주어야 합니다.

프로토콜에는 크게 프로퍼티와 메소드를 정의 해줄 수 있습니다. 그러면 하나씩 어떻게 정의할 수 있는지 살펴보겠습니다.

프로퍼티 정의

프로토콜로 프로퍼티를 정의할 때는 크게 두가지가 신경 쓰입니다.

  • let, var 의 정의
  • get set의 정의

먼저 let, var를 짚고 넘어가겠습니다. 프로토콜에는 let으로 정의할 수 없습니다. var로 정의해 놓은 변수를 let으로 구현할지 var로 구현할지는 구현하는 사람에게 달렸습니다.

protocol Student {
    var name: String { get }
    var grade: Int? { get }
}

struct Leeo: Student {
    let name: String
    let grade: Int?
}

struct Vabat: Student {
    var name: String
    var grade: Int?
}

let leeo = Leeo(name: "hyunho", grade: nil)
let vabat = Vabat(name: "jihye", grade: 3)
print(leeo) // Leeo(name: "hyunho", grade: nil)
print(vabat) // Vabat(name: "jihye", grade: Optional(3))

그러므로 let, var로 고민하지 않겠습니다.

get set의 정의는 제약 이라는 키워드로 생각하면 쉽습니다. get은 일단 무조건 있어야 하므로 생략하겠습니다. set키워드의 제약을 걸지 않으면, set을 구현해도, 구현하지 않아도 상관없습니다. 하지만 set이 정의 되어있으면 반드시 구현 해주어야 프로토콜을 준수한다고 할 수 있겠죠? 아래의 예를 하나 들어보겠습니다.

protocol Student {
    var name: String { get set }
    var grade: Int? { get }
}

struct Leeo: Student {
    var myName: String
    var name: String {
        get {
            return self.myName
        }

        set {
            self.myName = newValue
        }
    }
    var grade: Int?
}


var leeo = Leeo(myName: "leeo", grade: nil)
print(leeo)
leeo.name = "hyunho"
print(leeo)

이런식으로 name은 get과 set을 모두 구현해주어야 합니다. 그리고 당연한 이야기 지만, name은 var로 정의되어야 하겠죠? 값이 변해야 하니까요!

프로퍼티 정리

  • var 키워드를 붙여서 정리
  • set을 꼭 구현해야 하는 경우에는 정의 해주기 이렇게 정리 해 볼 수 있겠습니다.

메소드 정의

프로퍼티를 정의한 다음에 생각나는 것은 그렇죠 메소드 입니다. 우리는 이런 기능을 할 것이다 라고 정의하고 싶을 때 어떻게 해야할지 알아 볼 것입니다.

프로퍼티 때와 마찬가지로 func 앞에 붙는 키워드들, mutating, static 이런 것들이 신경쓰입니다.

하나씩 생각해보면 우리가 메소드를 만들 때 붙이는 키워드와 같은 역할을 하는 키워들이니 우리에게 필요한 메소드만 정의하면 됩니다.

protocol Student {
    var name: String { get set }
    var grade: Int? { get }

    func sayHi()
}

위와 같이 메소드 정의 하듯이 정의하면 되는 것이죠

정리

그래서 프로토콜은 어디어 어떻게 쓰는 것이냐에 대해서는 좀 더 설계를 공부해야할 것 같습니다. 이번에는 설계된 프로토콜을 보고 채택을 했을 때, 어떤 구현들을 해야하는 것일지를 예측하고 이해하는데 만족해야겠습니다.

댓글

이 블로그의 인기 게시물

[IOS] AppDelegate는 뭐하는 녀석이지?

[git] git의 upstream과 origin 헷갈리는 사람 손!

[git] Github 이슈 라벨(issue labels)