Nested type은 어떤 상황에 유용하게 사용될까?
//정의부
struct BlackjackCard {
enum Suit: Character {
case spades = "♠",
case hearts = "♡",
case diamonds = "♢",
case clubs = "♣"
}
let suit: Suit
}
//호출부
print(BlackjackCard.Suit.spades)
아래는 게임판매목록(Game)을 명시하는 두 열거형 타입을 Nested type으로 정의한 것과 그렇지 않은 코드입니다. 두 타입은 서로 역할이 유사하므로 구분을 위해 단순히 Game
으로는 Naming이 불가하고 SteamAsiaGame
/SteamEuropeGame
과 같이 다소 불편한? 이름이 탄생합니다
지금의 예시는 depth가 하나뿐이므로 그렇게 길지 않지만, 경우에 따라 깊은 계층 구조를 가질 경우 매우 길고 불편한 이름이 탄생하게 될 것입니다 (ex. SteamAsiaKoreaSeoulRollPlayingGame
)
이렇게 계층구조를 가지는 경우 Nested type으로 설계하는 것이 훨씬 깔끔한 Naming을 만들기에 용이합니다
//🔴 Without Nested type
struct SteamAsia {
let gameList: [SteamAsiaGame]
}
enum SteamAsiaGame: String {
case first = "LOL",
case second = "BattleGround",
case third = "GetAmped"
}
struct SteamEurope {
let gameList: [SteamEuropeGame]
}
enum SteamEuropeGame: String {
case first = "LOL",
case second = "WOW",
case third = "FIFA"
}
//🟢 With Nested type
struct SteamAsia {
enum Game: String {
case first = "LOL",
case second = "BattleGround",
case third = "GetAmped"
}
let gameList: [Game]
}
struct SteamEurope {
enum Game: String {
case first = "LOL",
case second = "WOW",
case third = "FIFA"
}
let gameList: [Game]
}
Game
타입과 SteamAsia
타입의 정의부가 붙어 있으므로, 별개로 정의되어 있을 때보다 두 타입 간 긴밀한 관계가 있음을 바로 알 수 있습니다
또한, 외부에서 Nested type을 언급할 때 SteamAsia.Game
와 같이 상위타입의 이름이 prefix로 붙어야 하므로 두 타입의 관계가 포함관계임을 파악할 수 있습니다
기본적으로, 한 번에 읽어야 하는 코드 덩어리가 커질수록 가독성은 나빠집니다
따라서 Nested type의 덩치가 너무 크다면 서로 분리하여 한 번에 읽어야 하는 코드량을 줄이는 것을 고려해 볼 만한 것 같습니다