언어/Kotlin
[Kotlin In Action] 로컬 함수와 확장
원석💎-dev
2022. 4. 25. 00:07
반응형
흔히 발생하는 중복코드를 로컬 함수를 통해 어떻게 제거할 수 있는지 살펴보자.
1. 로컬 함수
아래 코드는 중복이 발생한 코드이다.
class User(
val id: Int,
val name: String,
val address: String,
)
fun saveUser(user: User) {
if (user.name.isEmpty()) { // 중복 코드
throw IllegalArgumentException("Can't save user ${user.id}: empty Name")
}
if (user.address.isEmpty()) { // 중복 코드
throw IllegalArgumentException("Can't save user ${user.id}: empty Address")
}
// 사용자 저장
.
.
.
}
아래 코드는 확장 함수를 사용해 중복을 제거한 코드이다.
fun saveUser(user: User) {
fun validate(
user: User,
value: String,
fieldName: String,
) {
if (value.isEmpty()) {
throw IllegalArgumentException("Can't save user ${user.id}: empty $fieldName")
}
}
validate(user, user.name, "Name")
validate(user, user.address, "Address")
// 사용자 저장
.
.
.
}
위 코드로 중복이 어느정도 제거되었다. 하지만 ${user.id}를 위해 user를 파라미터로 넘겨야하는 하는 점이 아쉽다. 다행이도 로컬 함수는 자신이 속한 바깥 함수의 모든 파라미터와 변수를 사용할 수 있다.
fun saveUser(user: User) {
fun validate(
value: String,
fieldName: String,
) {
if (value.isEmpty()) {
throw IllegalArgumentException("Can't save user ${user.id}: empty $fieldName")
}
}
validate(user.name, "Name")
validate(user.address, "Address")
// 사용자 저장
.
.
.
}
2. 확장 함수
위의 코드에 확장 함수를 사용하여 검증로직을 더 깔끔하게 뽑아낼 수 있다.
class User(
val id: Int,
val name: String,
val address: String,
)
fun User.validateBeforeSave() {
fun validate(
value: String,
fieldName: String,
) {
if (value.isEmpty()) {
// user의 프로퍼티 직접 사용가능
throw IllegalArgumentException("Can't save user ${this.id}: empty $fieldName")
}
}
validate(user.name, "Name")
validate(user.address, "Address")
}
fun saveUser(user: User) {
User.validateBeforeSave() // 확장함수 호출
// 사용자 저장
.
.
.
}
3. 좀 더 나아가서 (require)
[require 블록]을 사용하면 조금 더 가독성 좋은 코드를 작성 할 수 있다.
class User(
val id: Int,
val name: String,
val address: String,
)
fun User.validateBeforeSave() {
fun validate(
value: String,
fieldName: String,
) {
require(value.isEmpty()) { "Can't save user ${this.id}: empty $fieldName" }
}
validate(user.name, "Name")
validate(user.address, "Address")
}
fun saveUser(user: User) {
User.validateBeforeSave() // 확장함수 호출
// 사용자 저장
.
.
.
}
반응형