코드를 작성하다보면 날 것의 숫자나 텍스트를 적용해야 하는 경우가 있습니다. 예를 들어 JSON 파일로부터 데이터를 불러올 때, 파일의 이름을 작성한다거나, UI 요소에 적용될 접미 접두사 같은 요소들이 있겠죠.
이와 같은 날 것의 코드는 최초 작성자를 포함하여 동료들까지 실수를 일으킬 수 있는 요소가 될 수 있기에 별도의 장소에 함께 작성해두었다가 불러서 사용하는 것이 더 좋은 선택일 수 있습니다. 날 것의 코드에 의미를 부여해줄 수 있기도 하구요.
으잉? "exposition_universelle_1900"이 뭐람.. 파일 이름인가? 파일 이름 바뀌면 다른 곳에서도 다 바꿔야겠네.. 애초에 파일 이름이 맞는지도 잘 모르겠어.
충분히 이런 생각을 할 수 있다고 생각합니다. 이를 미연에 방지하려면 이러한 날 것의 코드를 모아서 관리하는 Name space
를 만들 것을 고려해볼 수 있습니다. 아래 코드를 보실까요?
enum ExpoData {
static let expoIntroduction: String = "exposition_universelle_1900"
static let artworks: String = "items"
static let posterImage: String = "poster"
}
Expo
라는 것이 프로젝트임을 알고있다면, 이 열거 타입은 데이터와 관련된 타입이라는 것을 알 수 있겠네요. 소개와 관련된 자료는 expoIntroduction
이, 미술품과 관련된 자료는 artworks
가 가지고 있는 것도 파악이 가능할 것입니다. 그럼 이미지로 보여드렸던 내용도 아래와 같이 적용할 수 있겠죠.
파일 이름이 변경돼도 이 코드에서 변경할 점은 없겠네요. ExpoData
라는 Name space
에서 변경해주면 다른 파일에서 적용한 내용들도 함께 변경할 수 있으니까요.
마찬가지로 UI 요소에 적용되는 날 것의 텍스트도 이러한 방식으로 관리할 수 있습니다. JSON 데이터에서 48130300
이라는 숫자만 제공하는 상황에서 아래 이미지와 같이 방문객:
, 명
에 해당하는 내용을 접두, 접미어로 붙여주어야할 때 아래와 같이 적용하시면 됩니다.
어떤가요? 저는 날 것의 텍스트가 코드에서 살아 숨쉬는 것 보다 훨씬 좋다고 생각합니다. 텍스트 뿐만 아니라 정수나 소수 모든 타입을 이러한 형식으로 선언하여 원하는 때마다 반복적으로 꺼내 쓸 수 있습니다!
아래가 궁금하시다면 계속해서 읽어주세요~!
사실 Name space
를 정의하는데 열거 타입을 꼭 사용하여야 하거나 타입 프로퍼티를 활용하지 않아도 됩니다. 구조체를 이용하거나 열거 타입의 case - rawValue
를 활용해도 되죠. 이를 활용하면 아래와 같이 작성이 가능합니다.
// 구조체로 Name space를 작성하는 경우
struct ExpoData {
static let expoIntroduction: String = "exposition_universelle_1900"
static let artworks: String = "items"
static let posterImage: String = "poster"
}
// 열거 타입의 case - rawValue 형식으로 작성하는 경우
enum ExpoData: String {
case expoIntroduction = "exposition_universelle_1900"
case artworks = "items"
case posterImage = "poster"
}
실제로 위와 같은 형식으로 사용하기도 하는데요, 저는 개인적인 이유로 case
가 없이 타입 프로퍼티만으로 작성된 열거 타입을 활용합니다. 그 이유는 의도치 않은 인스턴스를 생성하지 않을 수 있기 때문이에요.
예를 들어, 위 예시와 같이 구조체로 Name space
를 작성한 경우 ExpoData()
를 통한 인스턴스 생성이 가능합니다. 아무 기능이 없더라도 의도치 않은 것임에는 틀림없죠. 이는 아래와 같이 이니셜라이저에 접근제한을 걸어둠으로써 인스턴스 생성을 방지할 수 있습니다.
// 구조체로 Name space를 작성하는 경우
struct ExpoData {
static let expoIntroduction: String = "exposition_universelle_1900"
static let artworks: String = "items"
static let posterImage: String = "poster"
private init() { }
}
저는 이렇게 이니셜라이저에 접근제한을 설정하는 것 또한 case
없는 열거 타입에 비해 불필요한 코드가 추가되는 것이라 생각해서 선호하지 않습니다.
case
- rawValue
로 정의된 경우와 비교두 번째 예시를 다시 가져와 보겠습니다.
// 열거 타입의 case - rawValue 형식으로 작성하는 경우
enum ExpoData: String {
case expoIntroduction = "exposition_universelle_1900"
case artworks = "items"
case posterImage = "poster"
}
제가 위와 같이 사용하지 않는 이유는 아래와 같습니다.
.rawValue
를 추가해야 한다는 번거로움이 있습니다. ExpoData.artworks.rawValue
처럼요. 저는 이렇듯 불필요하게 추가되는 요소를 선호하지 않습니다. case
가 존재하는 열거 타입의 경우 rawValue
를 활용해서 이니셜라이징할 수 있으므로 구조체와 마찬가지로 의도치 않은 인스턴스를 생성할 수 있다는 단점이 존재합니다.rawValue
가 하나의 타입 (위 예시의 경우 String
)으로 고정되므로 관련 있는 여러 타입을 하나의 Name Space
에서 관리할 수 없습니다.하지만 이 모든 것은 제 선호일 뿐이고 사용하시는 분들이 자유롭게 취사선택하시면 되겠습니다.
오늘도 읽어주셔서 감사합니다. 즐거운 하루 보내세요~!