[Swift]상수 파일(Constants) 관리하기
개요
- 코드 작성 중 반복되는 코드를 줄이고, 유지보수에 대한 고민을 개선 시켜줄 수 있는 간단한 방법 중 하나
가장 와닿는 예시를 들기 위해 UIColor를 대상으로 서술하겠습니다.
- 위와 같은 색상을 구현해야하는 경우의 예시
- 기본 제공되는 .green 등으론 커버가 안되는 상황
해당 색상의 Swift 코드는 아래와 같습니다.
색상코드는 해당 웹사이트를 통해 쉽게 구할 수 있습니다.
https://www.uicolor.io/
UIColor(red: 0.35, green: 0.80, blue: 0.56, alpha: 1.00)
UIColor(red: 0.26, green: 0.67, blue: 0.46, alpha: 1.00)
그런데 우리는 이 브랜드 색상 코드를 최소 10군데에선 쓰게 될 겁니다.
그떄마다 이 긴 코드를 외우는건 말도 안되고, 필요할때마다 매번 검색해서 쓰기엔 너무 귀찮잖아요?
Constants 파일 관리하기
Struct와 타입 프로퍼티를 통한 전역에서 접근 가능한 Constants 객체를 생성
struct Constants {
struct Color {
/// 색상 코드: #43AC75
static let ex_brandColor1 = UIColor(red: 0.26, green: 0.67, blue: 0.46, alpha: 1.00)
/// 색상 코드: #5ACC90
static let ex_brandColor2 = UIColor(red: 0.35, green: 0.80, blue: 0.56, alpha: 1.00)
}
}
이런식으로 작성하면 되겠죠
/// 를 통해 quick help를 작성하면 사용자 입장에서 좀 더 편할거같습니다.
이제 우리는 여기에 원하는대로 타입을 중첩해주면 되는거죠
처음 예시로 들었던 컬러도 가능할것이고 이미지 url이나 폰트등 반복되고 귀찮은 하드코딩 되는 모든것들이 될수도 있습니다.
좀 더 개선할 수 있을것 같습니다.
struct Constants {
struct Design {
struct Color{
/// 색상 코드: #43AC75
static let ex_brandColor1 = UIColor(red: 0.26, green: 0.67, blue: 0.46, alpha: 1.00)
/// 색상 코드: #5ACC90
static let ex_brandColor2 = UIColor(red: 0.35, green: 0.80, blue: 0.56, alpha: 1.00)
}
struct Image {
static let dogImage = UIImage(named: "dogdogdog")
}
}
struct Content{
struct TableViewItems {
static let items: [String] = [
"개인 정보",
"버전 정보",
"로그아웃"
]
}
}
}
이런식으로 취향대로, 팀간의 규칙에 맞춰서, 레이어를 나눠서 사용하면 더 좋을 것 같습니다.
디자인 관련된것들을 모아서 폰트, 이미지, 컬러등을 정의하고 사용할 수 있겠죠
뭐 각 팀간의 약속에 따라 테이블 뷰등을 만들때도
"이건 변경 가능성이 없어서 API를 통해 업데이트 하기보단 그냥 하드코딩으로 빠르게 넘어 가는게 이득인거같아!"
싶을때의 테이블 뷰 아이템을 담아놓는 용도로 써도 괜찮을것같아요
물론 가장 빛나는 경우는 “반복되는” 코드인 경우겠지만, 어쨌든 한 파일에서 이런 상수를 몰아서 관리 할 수 있다는 점, 하드코딩을 줄일 수 있다는 점,
오타를 통한 휴먼 에러를 줄이고, 변경시에도 해당 파일에서 관리해주면 모든 공간에서의 변경이 이뤄진다는 장점등이 있습니다.
그럼 사용할땐 이런식으로 사용 될 겁니다.
testView.backgroundColor = Constants.Design.Color.ex_brandColor1
하지만 너무 뎁스가 깊어지면 디미터 법칙에 어긋날수도 있다는점을 고려하면 더 좋은 코드를 만들 수 있을거라고 생각합니다.
확장자를 통한 관리
추가로 제가 자주 사용하는 또 하나의 방식은 아래와 같습니다.
extension UIColor {
/// 색상 코드: #43AC75
static let ex_brandColor1 = UIColor(red: 0.26, green: 0.67, blue: 0.46, alpha: 1.00)
/// 색상 코드: #5ACC90
static let ex_brandColor2 = UIColor(red: 0.35, green: 0.80, blue: 0.56, alpha: 1.00)
}
사실 비슷한 동작 방식으로 볼 수 있습니다.
확장과 타입 프로퍼티를 이용한 방법입니다.
저는 이 방법을 사실 조금 더 선호합니다.
무얼 선택할까?
당연하지만, 각자의 장 단점이 있을것같습니다
예시를 컬러로 들었을때의 두가지 방법이지만, 다른 경우까지 모두 생각하면 완벽히 같은 용도를 가지지도 않았구요.
상수 파일 관리
장점:
- 중앙관리: 가장 큰 장점은 모든 상수를 한곳에서 관리 하니, 수정, 추가, 삭제등이 용이할겁니다
- 간단한 구조: 상수를 찾거나 추가할 때 한 파일만 보면 되니 구조가 단순하고 초기에 작성하기 편할거라고 생각합니다.
단점:
- 가독성의 저하: “구조가 커졌을때” 는 오히려 간단한 구조가 독이되어 가독성이 크게 떨어질 수 있습니다.
확장자를 통한 관리
장점:
- 코드의 응집력: 특정 타입과 관련된 상수나 메서드를 그 타입의 확장자로 정의하면 관련된 코드를 한곳에 모아놓아 코드의 응집력이 높아질겁니다
- 가독성: 관련된 메서드와 프로퍼티가 그 타입의 정의와 함께 있으니 해당 타입에 대한 이해가 좀 더 용이할거라고 생각됩니다.
단점:
- 분산 관리: 여러 타입의 확장자에 상수들이 분산되어 있는 경우, 한곳에서 모든 상수를 관리하기 어려워지니 특정 상수를 찾기 위해 여러 확장자를 찾아봐야하는점은 번거로울 겁니다.