접근제어

피터·2022년 8월 6일
post-thumbnail

객체지향 프로그래밍 패러다임에서 은닉화는 중요한 개념 중 하나 입니다. 이를 구현하기 위한 핵심 기능이 접근제어 입니다.

💡 은닉화란?

접근제어란

접근제어는 코드끼리 상호작용을 할 때 파일 간 또는 모듈 간에 접근을 제한할 수 있는 기능입니다. 접근제어를 통해 코드의 상세 구현은 숨기고 허용된 기능만 사용하는 인터페이스를 제공할 수 있습니다.

접근제어의 필요성

객체지향 프로그래밍 패러다임에서 중요한 캡슐화와 은닉화를 구현하는 이유는 외부에서 보거나 접근하면 안 되는 코드가 있기 때문입니다.

모듈과 소스파일

스위프트에서 접근제어는 모듈과 소스파일 기반으로 설계되었습니다.

  • 모듈
    • 배포할 코드의 묶음 단위
    • 하나의 프레임워크나 라이프러리 또는 애플리케이션이 모듈 단위가 될 수 있음
    • 스위프트에서는 import 키워드를 사용해 불러옴
  • 소스파일
    • 하나의 스위프트 소스 코드 파일
    • 자바 혹은 Objective-C와 같은 기존 프로그래밍 언어에서는 통상 파일 하나에 타입 하나만 정의하는 반면, 스위프트에서도 보통 파일 하나에 타입 하나만 정의하지만, 여러 타입이나 함수 등 많은 것을 정의하거나 구현할 수도 있음

접근수준

접근수준(Access Level) 키워드를 통해 구현할 수 있습니다. 각 타입, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도 접근수준을 지정할 수 있습니다.

  • 접근수준 명명 키워드 (5가지)
    • open, public, internal(default 값), fileprivate, private

공개 접근수준 - public

public은 어디서든 쓰일 수 있습니다. 자신이 구현된 소스파일은 물로느, 그 소스파일에 속해 잇는 모듈, 그 모듈을 가져다 쓰는 모듈 등 모든 곳에서 사용할 수 있습니다. 주로 프레임워크에서 외부와 연결된 인터페이스를 구현하는데 많이 쓰입니다.

// 스위프트 표준 라이브러리의 기본 요소는 모두 공개 접근수준으로 구현
public struct Bool {
	public init()
}

개방 접근수준 - open

open 키워드로 지정할 수 잇는 개방 접근수준은 공개 접근수준 이상으로 높은 접근수준이며, 클래스와 클래스의 멤버에서만 사용할 수 있습니다.

그렇다면 공개 접근수준과 무슨 차이가 있을까?

  • 개방(open) 접근수준을 제외한 다른 모든 접근수준의 클래스는 그 클래스가 정의된 모듈 안에서만 상속할 수 있습니다.
  • 개방(open) 접근수준을 제외한 다른 모든 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 안에서만 재정의할 수 있습니다.
  • 개방(open) 접근수준의 클래스는 그 클래스가 정의된 모듈 밖의 다른 모듈에서도 상속할 수 있습니다.
  • 개방(open) 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 밖의 다른 모듈에서도 재정의할 수 있습니다.

클래스를 개방 접근수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 부모클래스로 사용하겠다는 목적으로 클래스를 설계하고 코드를 작성했음을 의미합니다.

내부 접근수준 - internal

모든 요소에 암묵적으로 지정하는 기본 접근수준입니다. 내부 접근수준으로 지정된 요소는 소스파일에 속해 있는 모듈 어디서든 쓰일 수 있습니다. 다만 그 모듈을 가져다 쓰는 외부 모듈에서는 접근할 수 없습니다.

보통 외부에서 사용할 클래스나 구조체가 아니며, 모듈 내부에서 광역적으로 사용할 경우 내부 접근수준을 지정합니다.

파일외부비공개 접근수준 - fileprivate

파일외부비공개 접근수준으로 지정된 요소는 그 요소가 구현된 소스파일 내부에서만 사용할 수 있습니다.

비공개 접근수준 - private

비공개 접근수준으로 지정된 요소는 그 기능을 유지하고 구현한 범위 내에서만 사용할 수 있습니다. 비공개 접근수준으로 지정한 기능은 심지어 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없습니다.

접근제어 구현

타입이나 프로퍼티 앞에 접근수준 5가지 키워드 중 적절한 접근수준을 골라 표기해주면 됩니다. 단, internal은 기본 접근수준이므로 굳이 표기해주지 않아도 됩니다.

접근제어 구현 참고사항

모든 타입에 적용되는 접근수준의 규칙은 ‘상위 요소보다 하위 요소가 더 높은 접근수준을 가질 수 없다.’입니다. 예를 들어, private으로 정의된 구조체 내부의 프로퍼티로 public 프로퍼티를 정의할 수 없습니다. 또는 public로 정의된 메서드에서 매개변수나 반환 타입을 private으로 할 수 없습니다.

열거형의 접근수준을 구현할 대 열거형 내부의 각 case 별로 따로 접근수준을 부여할 수는 없습니다. 각 case의 접근수준은 열거형 자체의 접근수준을 따릅니다. 또한 열거형의 원시 값, 연관 값 타입으로 열거형 접근수준보다 낮은 접근수준의 타입이 올 수는 없습니다.

private와 fileprivate

private은 같은 타입 내부에서만 사용 가능합니다.(extension에서도 가능)

fileprivate은 같은 소스파일 내부에서만 사용 가능한 접근수준으로 다른 타입이어도 같은 소스파일에 있다면 사용 가능합니다. 반면 소스 파일 밖에서 접근하는 것은 불가능합니다.

읽기 전용(get only) 구현

구조체 또는 클래스를 사용하여 저장 프로퍼티를 구현할 때는 허용된 접근수준에서 프로퍼티 값을 가져(get)갈 수 있습니다. 하지만 값을 변경할 수 없도록 구현하고 싶다면 어떻게 해야 할까요?

설정자(Setter)만 더 낮은 접근수준을 갖도록 제한할 수 있습니다.

설정자 접근수준 제한은 프로퍼티, 서브스크립트, 변수 등에 적용될 수 있으며, 해당 요소의 접근수준보다 같거나 낮은 수준으로 제한해주어야 합니다.

접근수준(set)

public struct SomeType {
    public private(set) publicGetOnlyProperty: Int = 3
    
    private(set) internalGetOnlyProperty: Int = 5
}

자료 출처: 야곰 스위프트 프로그래밍 3판

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."
profile
iOS 개발자입니다.

0개의 댓글