티스토리 뷰

[Swift] 프로토콜과 제네릭 그리고 열거형


Swift를 활용한 프로그램 설계 규칙에 있어서 메소드 인터페이스가 동일하면 프로토콜을 활용하고 로직은 동일하나 타입만 다르다면 제네릭을 활용하는 것이 좋은 설계 규칙 중 하나로 뽑힙니다. 오늘은 프로토콜(Protocol)제네릭(Generics)을 같이 사용해보고 이를 통해 배운점을 기록해보고자 합니다.


다음은 프로토콜에 관해 제가 작성한 포스팅들입니다.


다음은 제네릭을 사용해 iOS에서 코드를 줄여본 경험을 작성한 포스팅입니다.


프로토콜과 제너릭에 대한 기본적인 지식이 필요로 하는 포스팅입니다.


프로토콜(Protocol) 과 제네릭(Generics)

인터페이스가 동일하다면 프로토콜로 이를 묶어서 추후에 같은 인터페이스를 필요로 하는 타입에 통일된 인터페이스를 제공할 수 있습니다. 그 안의 로직은 다양할 수 있습니다.


그리고 구현 로직은 완전 동일하지만 타입만 다르다면 우리는 이것을 제네릭을 이용해 코드의 중복을 방지할 수 있습니다. 프로토콜에 대한 지식이 있으신 분들은 프로토콜도 하나의 타입이라는 것도 알고 계실 겁니다. 그래서 저는 이 둘을 활용한다면 보다 코드를 추상화할 수 있고 중복을 제거할 수 있을 것이라고 생각하여 이 둘을 함께 사용해보았습니다.


저는 같은 분류에 속하나 서로 다른 성격(타입)을 갖는 두 enum을 하나의 분류라는 의미에서 동일한 프로토콜을 준수하도록 하였습니다. 그리고 같은 분류 속에서 속하는 이 둘은 동일한 로직을 갖기 때문에 이 둘을 제네릭을 활용하여 코드의 중복을 제거해보고자 하였습니다.


Implementation


enum 타입을 추후에 제네릭으로 묶어 사용하기 위해 GroupProtocolRawReresentable을 체택합니다. 그리고 GroupProtocol을 준수하는 두 enum 타입은 RawRepresentable을 이미 준수하고 있는 타입이기 때문에 따로 RawRepresentable 프로토콜을 추가로 구현해주지 않아도 됩니다.


그리고 이 enum들의 동일한 로직을 제네릭으로 묶어 놓은 구조체를 다음과 같이 작성하였습니다.


AEntityBEntity 모두 RawValueString 이므로 이들의 로직을 묶어준 ConmonLogic 에서 사용하게 될 TRawValueString 인 타입에 한정해야 합니다. 이렇게 구조체를 정의할 때 타입이 한정된 T는 구조체 안에서 따로 어떠한 제한을 걸어 사용할 필요 없이 바로 사용할 수 있게 됩니다.


이렇게 TRawRepresentable을 체택한 GroupProtocol을 체택하였으므로 T를 반환하는 메소드를 다음과 같이 작성할 수 있습니다.


여기서 T를 생성할 때 사용되는 rawValuesomething은 무슨 타입이 될까요? 바로 String 입니다. 다른 타입이 될 순 없습니다. 왜냐하면 CommonLogic 구조체를 정의할 때 TRawValue 타입을 String으로 한정해주었기 때문입니다.


그리고 만일 프로토콜 내부에서 associatedtype이 선언되어 있거나 Self가 사용된다면 그 프로토콜은 제네릭의 한정 프로토콜으로만 사용할 수 있습니다. 그 뜻이 무엇인지 코드로 살펴보도록 하겠습니다.



이렇게 GroupProtocol을 직접적으로 사용할 수 없기 때문에 우리는 코드를 다음과 같이 수정해주어야 합니다.



마무리

제네릭을 사용하는 것은 아직 많이 낯섭니다. 그렇기 때문에 사용할 때마다 에러 메시지와 마주치게 되지만 이러한 에러들을 수정해나가게 되면서 제네릭의 강력함에 매번 놀라곤 합니다. 제네릭을 보다 적극적으로 활용하여 코드를 깨끗하게 유지하는 습관을 들여야 할 것 같습니다. 감사합니다.


참고자료


  1. Enumerations
  2. Generics
  3. How to fix the error Protocol can only be used as a generic constraint because it has Self or associated type requirements

 


'Swift + iOS > Swift' 카테고리의 다른 글

[Swift] Swift에서 정규표현식 사용하기  (0) 2018.08.11
[Swift] Functor and Monad in Swift  (3) 2018.07.05
[Swift] Hashable  (0) 2018.06.03
[Swift] 접근제어 Access Control  (0) 2018.01.21
[Swift] String 좀 더 알아보기 (2)  (0) 2018.01.09
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함