해당 포스팅은 https://medium.com/@domen.lanisnik/5-kotlin-tips-for-a-cleaner-codebase-3582f2e4e2af 번역한 글입니다.
💡 이는 단지 제안일 뿐이며, 올바른 방법임을 의미하지는 않음. 코드 스타일은 팀의 선호도에 따라 다름.
접근 제어자
public
: 모듈 내부의 모든 클래스와 이 모듈에 의존하는 모든 모듈에 표시되는 기본 수정자internal
: 모듈 내부의 모든 클래스에 표시되지만 모듈 외부에는 표시되지 않음.private
: 파일이나 클래스 내부에서만 볼 수 있음.protected
: 클래스의 멤버(함수, 프로퍼티)도 이를 상속하는 모든 클래스에 표시됨.oepn
사용.internal
접근 제어자를 사용할 것.// top-level declaration
fun String.isValidUsername(): Boolean {
return this.matches(Regex("^[a-zA-Z0-9._-]{3,15}\$"))
}
isValidUsername
함수가 제안 목록에 표시됨.함수 체이닝
private fun squareIfPositive(someNumber: Int): Int {
return someNumber.takeIf { it > 0 }?.let { it * it } ?: 0
}
// or
private fun squareIfPositive(someNumber: Int): Int {
return someNumber
.takeIf { it > 0 }
?.let { it * it }
?: 0
}
자바와 유사한 방식
// option 1
private fun squareIfPositive(someNumber: Int): Int {
return if (someNumber > 0) {
someNumber * someNumber
} else {
0
}
}
// option 2
private fun squareIfPositive(someNumber: Int): Int {
if (someNumber <= 0) {
return 0
}
return someNumber * someNumber
}
suspend fun authenticateUser(username: String): Pair<String, String> {
// perform authentication logic
return Pair("accessToken", "refreshToken")
}
authenticateUser
함수를 사용할 경우 authenticateUser.first()
와 같이 사용해야함.suspend fun authenticateUser(username: String): AuthenticationTokens {
// perform authentication logic
return AuthenticationTokens(
accessToken = "accessToken",
refreshToken = "refreshToken"
)
}
data class AuthenticationTokens(
val accessToken: String,
val refreshToken: String
)
enum class
, sealed class
, sealed interface
else
는 새 값이 추가될 때 잠재적인 버그가 발생할 수 있음.
enum class ProfileAnalyticsEvent {
PROFILE_OPENED,
PROFILE_EDITED,
PROFILE_SAVED,
PROFILE_DELETED
}
fun onAnalyticsEvent(event: ProfileAnalyticsEvent) {
when (event) {
ProfileAnalyticsEvent.PROFILE_OPENED -> trackProfileOpened()
ProfileAnalyticsEvent.PROFILE_EDITED -> trackProfileEdited()
ProfileAnalyticsEvent.PROFILE_SAVED -> trackProfileSaved()
else -> trackProfileDeleted()
}
}
PROFILE_DELETED
가 추가됐다면, 이 이벤트를 놓치고 else로 인해 trackProfileDeleted
이 호출될 것.when
을 철저하게 작성하면 이러한 문제를 쉽게 피할 수 있음.fun onAnalyticsEvent(event: ProfileAnalyticsEvent) {
when (event) {
ProfileAnalyticsEvent.PROFILE_OPENED -> trackProfileOpened()
ProfileAnalyticsEvent.PROFILE_EDITED -> trackProfileEdited()
ProfileAnalyticsEvent.PROFILE_SAVED -> trackProfileSaved()
ProfileAnalyticsEvent.PROFILE_DELETED -> trackProfileDeleted()
ProfileAnalyticsEvent.PROFILE_CANCELLED -> trackProfileCancelled()
}
}