[코틀린인액션] 로컬 함수를 사용하여 코드 중복 제거

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")
    }
    // Save user to the database
}

fun main() {
    val user = User(1, "John", 25, "Main St.")
    saveUser(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")
    // Save user to the database
}

fun main() {
    val user = User(1, "John", 25, "Main St.")
    saveUser(user)
}
  • 로컬함수는 자신의 정의된 바깥 함수의 모든 변수와 파라미터에 접근이 가능하ㄷ
    • 이를 활용해 불필요한 파라미터 전달을 줄일 수 있음.

장점

  1. 코드 중복의 감소
  1. 가독성 증대
  1. 유지보수 용이

물론, 중복된다고 모두 로컬함수로 만들어버리면 오히려 알아보기 어려울수도있다..

클린코드에서 중복을 제거하라고했는데요? 하고 했는데요 ..라면?

를 한번 보자.

User 클래스에 대한 확장 함수

fun User.validateBeforeSave() {
    fun validate(value: String, fieldName: String) {
        if (value.isEmpty()) {
            throw IllegalArgumentException("Can't save user $id: empty $fieldName")
        }
    }
    
    validate(name, "Name")
    validate(address, "Address")
}

fun saveUser(user: User) {
    user.validateBeforeSave()
    // Save user to the database
}

fun main() {
    val user = User(1, "John", 25, "Main St.")
    saveUser(user)
}
  • User 클래스의 객체에 대한 검증 로직을 User 클래스의 확장 함수로 추출함.
  • 확장 함수를 사용하면 기존 클래스를 수정하지 않고 새로운 기능을 추가할 수 있다.
    • 클래스의 기능은 확장하고 싶지만, 클래스 자체를 변경하고 싶지 않는 경우 유용하다.

관련 로직을 User 클래스에 직접 연결함으로 코드를 더욱 직관적으로 조직할 수 있다.


Uploaded by N2T