본문 바로가기
iOS

[29일차] Protocol이란?

by 디지털노마더 2020. 8. 27.

아래의 글은 '군옥수수님의 포스팅' 내용을 발췌한 내용입니다.

 

Swift를 잘 다루고 여러 샘플 코드들을 정확히 이해하려면 protocol은 완벽히 익히고 있어야 한다고 생각합니다. 어떻게 보면 Swift의 강력한 기능 중 하나가 protocol이라고 생각됩니다. 

그럼 지금부터 protocol에 대해서 천천히 알아가는 시간을 갖도록 하겠습니다.

애플의 공식문서에 정의된 protocol의 정의는 다음과 같습니다.

 

"A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality."

 

직역하자면 다음과 같습니다.

 

"protocol은 특정 작업 혹은 기능들을 구현하기 위한 메소드, 프로퍼티 그리고 기타 다른 요구사항들의 청사진이다."


Protocol이란 무엇인가?

: protocol은 해당 이름에 걸맞는 기능을 하기 위해서 구현해야 하는 것들의 리스트입니다. (Java의 interface와 유사한 개념)

 

개발을 할 때 네이밍을 잘하는 것이 중요한 이유 중 하나가 해당 변수, 클래스, 구조체 그리고 Swift에서는 protocol까지 그것들의 이름만 봐도 역할이 명확하게 나타나야 하기 때문입니다.

 

여러분이 만역 “컴퓨터공학과 학부생” 이라는 타이틀을 갖고 그에 알맞은 능력을 갖고 싶다면 몇몇 과목들을 이수해야 합니다. 그리고 기본적으로 갖춰야 할 장비들도 존재합니다.

여기서 우리는 “컴퓨터공학과 학부생” 프로토콜을 설계해볼 수 있습니다.


컴공생이라면 노트북을 보유해야 합니다. 하지만 노트북이 없고 집에 데스크탑으로 보유하고 있을 수도 있습니다. 또한 필수로 이수해야 할 과목들이 존재합니다. 

 

  1. 자료구조
  2. 운영체제
  3. 네트워크

 

또한 필수는 아니더라도 개인의 진로와 방향에 따라 부수적으로 수강할 수도 안 할 수도 있는 과목들도 존재합니다.

 

  1. 그래픽스

그럼 이러한 시나리오를 바탕으로 프로토콜을 작성해보도록 하겠습니다.

 

protocol ComputerScienceStudent{
    var name:String { get }
    var laptop:String? { get set }
    
    func doDataStructure()
    func doOperatingSystem()
    func doNetwork()
}

 

기본적인 프로퍼티로 이름을 지칭하는 name이 있을 수 있습니다. 또한 위에서 언급했던 것과 마찬가지로 노트북을 보유하고 있을수도 없을 수도 있기 때문에 laptop은 옵셔널 타입으로 지정하였습니다.

 

여기서 먼저 살펴보아야 할 것은 프로퍼티의 { get }  { get set }입니다.

 

  • 우선 { get }은 프로토콜을 따를 때 해당 변수는 { get } 과 { get set } 둘 중 하나만 구현해도 됩니다.
class Student:ComputerScienceStudent{
    var _name:String = ""
    var name:String{
        get{
            return self._name
        }
        set{
            self._name = newValue
        }
        
        /*
            method code
        */
    }
}

주의해야 할 것은 { set }만 구현할 수는 없습니다.

 

  • 다음은 { get set }입니다. { get set }은 프로토콜을 따를 때 해당 변수는 반드시 { get set }을 모두 구현해야 한다는 것입니다. 위의 { get } 처럼 둘 중 하나만 구현하는 것이 아니라 { get set } 모두 구현을 해야 합니다.
class Student:ComputerScienceStudent{
    var _laptop:String?
    var laptop:String?{
        get{
            return self._laptop
        }
        
        set{
            self._laptop = newValue
        }
    }
    
    /*
    // Error : get과 set모두 구현해야 한다.
    var laptop:String?{
        get {
            return self._laptop
        }
    }
    */
    
    /*
        method code
    */
}

또한 필수로 구현해야 하는 메소드들도 반드시 구현을 해야 합니다.

class Student:ComputerScienceStudent{
        /*
            property code
        */
        
    func doDataStructure(){
        print("I love Data Structure")
    }
    func doOperatingSystem(){
        print("It's boring")    
    }
    func doNetwork(){
        print("I like Network")
    }
}

일반적으로 선언된 메소드들은 하나라도 구현하지 않으면 에러를 발생시킵니다.


나열된 메소드들은 반드시 모두 구현해야 하나?!

 

위에서 언급했던 것과 같이 “그래픽스” 수업 같은 경우에는 학생에 따라서 들을 수도 있지만 듣지 않을 수도 있습니다. 이와 같이 선택적인 메소드 구현을 위해서는 다음과 같이 @objc 키워드와 optional을 이용하면 됩니다.

@objc protocol ComputerScienceStudent{
    var name:String { get }
    var laptop:String? { get set }
    
    func doDataStructure()
    func doOperatingSystem()
    func doNetwork()
    
    @objc optional func doGraphics()
}

 

 

이렇게 protocol키워드 앞과 해당 함수의 앞에 위와 같이 @objc optional 키워드를 붙여주면 됩니다.


마무리

나열된 메소드들은 반드시 모두 구현해야 하나?!

 

프로토콜의 채택은 상속과 달리 class뿐만아니라 enum, struct 에도 적용이 가능합니다. 또한 delegation pattern과 protocol oriented programming에서도 프로토콜이 사용됩니다.

댓글