이전 글에서는 swift 의 5가지 접근 제어자 와 @testable 에 대해 살펴봤었지요. swift 접근 제어자 는 open, public, internal, fileprivate, private 다섯 단계로 나뉘며, 이 중 default로 적용되는 값은 internal, 즉 모듈 내부에서 사용할 수 있는 단계라고 설명한 바 있습니다.
open과 public은 해당 모듈을 import한 다른 모듈에서도 사용이 가능하며, 특히 open은 subclass, override가 허용되는, 가장 자유도가 높은 단계입니다. public은 공개, open은 거기에 수정 권한까지 더한 단계인 것입니다.
fileprivate, private는 함수의 구현 사항을 외부에 드러내지 않기 위해 사용되는 접근 제어자이며, fileprivate 단계로 설정된 타입, 함수는해당 소스파일을 벗어나 사용할 수 없으며, private는 다른 프로그래밍 언어에서 그러하듯, 선언된 영역을 벗어나 사용할 수 없습니다.
Access Control과 protected
다른 프로그래밍 언어는 보통 public, protected, private 세 단계로 나뉘는 Access Control을 가지고 있습니다. public은 subclass, override를 허용하고, protected는 해당 클래스를 상속한 클래스가 접근 가능한 객체, 함수 등을 나타내죠. private는 private하고요.
Apple은 swift의 접근 제어자를 디자인할 때, 두 가지 main use case를 상정하였습니다:
- private를 사용하여 클래스의 디테일한 부분을 앱의 다른 부분으로부터 숨기기
- internal을 사용하여 프레임워크의 디테일한 부분을 클라이언트 앱으로부터 숨기기
protected의 특징을 생각해봅시다. protected는 상속을 전제로 접근을 허용하며, private, internal과는 다른, 새로운 기준을 적용하는 것과 마찬가지입니다. 서브 클래스는 새로운 public 메소드나 속성을 통해 protected API를 외부로 노출하기 때문에, protect, 보호의 기능을 수행하는 것도 아닙니다. 또한, 새로운 상속은 어디서는 발생할 수 있으므로, 더나은 최적화 기회를 제공하지도 못합니다. 마지막으로, 불필요하게 제한적입니다. 서브 클래스가 무언가에 접근하는 건 허용하지만, 서브 클래스의 기능을 돕는, helper는 접근할 수 없습니다.
애플의 프레임워크는 서브 클래스에서 사용할 목적으로, API를 부분부분 나눠놓았습니다. 이러한 환경에서 protected는 제 기능을 발휘하지 못하며, protected 메소드는 두 가지 유형으로 변질될 가능성이 있습니다. "서브 클래스 밖에서 사용하기에 효과적이지 못한 메소드"와 "상속되어야 하지만 호출되지는 않는 메소드".
protected가 extension과 어떻게 상호작용 해야할 지도 명확하지 않습니다. 클래스의 extension이 protected 멤버에 접근해도 괜찮을까요? 서브 클래스가 수퍼 클래스의 protected 멤버에 접근하는 경우에는요? extension을 클래스와 같은 모듈에 선언하면 차이가 있어야 할까요?
현재의 접근 제어자 설계에 영향을 끼친 요소가 하나 더 있습니다. 바로 일부 남아있는 Objective-C 개발자 때문입니다. Objective-C 메소드와 속성은 일반적으로 public header 파일(.h)에 선언되어 있습니다. public 클래스의 일부가 프레임워크 내부에서만 사용되길 원하는 경우, 개발자는 두 번째 헤더 파일을 생성하여 클래스의 internal 한 요소를 선언합니다. 이러한 세 단계의 접근이 swift 의 public, private, internal에 대응합니다.
swift는 하나의, 상속과는 관련이 없는, 이해하기 쉬운 기준을 바탕으로 접근 제어 체계를 제공합니다. 이러한 모델은 기존 모델보다 더욱 단순하며, 가장 빈번하게 사용되는 요구 조건을 충족합니다: 클래스, 프레임워크의 구현 디테일을 외부와 단절시키는 것.
이 글은 다음 문서를 의역하여 서술하였습니다.
developer.apple.com/swift/blog/?id=11
'Swift' 카테고리의 다른 글
mac OS #Framework 생성, Cannot find #FUNCTION in scope error, Swift #접근제어자 와 @testable (0) | 2021.01.21 |
---|---|
#Postman 이용하여 #대부분의 데이터를 받아오는 방법! (0) | 2021.01.20 |
Objects and Classes - A Swift Tour 3일차 (0) | 2020.12.21 |
Functions and Closures - A Swift Tour 2일차 (0) | 2020.12.19 |
Control Flow - A Swift Tour 1일차 (0) | 2020.12.19 |