이펙티브 코틀린 Item 32: 추상화 규약을 지켜라

woga·2023년 9월 2일
0

코틀린 공부

목록 보기
35/54
post-thumbnail

규약은 개발자들의 단순한 합의. 그러나 위반할 수도 있다.

ex) 리플렉션 활용

class Employee {
	private val id: Int = 2
    override fun toString() = "User(id=$id)"
    
    private un privateFunction() {
    	println("Private function called")
    }
}

fun callPrivateFunction(employee: Employee) {
	employee::class.declaredMemberFunctions
    	.first{ it.name = "privateFunction" }
        .apply { isAccessible = true }
        .set(employee, newId)
}

fun main() {
	val employee = Employee()
    callPrivateFunction(employee)
    // print : Private Function called
    changeEmployeeId(employee, 1)
    print(employee) // print: User(id=1)
}

무언가를 할 수 있다는 건 그것을 해도 괜찮다는 의미는 아니다. 현재 코드는 private 프로퍼티와 private 함수의 이름과 같은 세부적인 정보에 매우 크게 의존하고 있다. 이러한 이름은 규약이라고 할 수 없어서 시한 폭탄과도 같다.

규약은 보증과 같다. 규약을 위반하면 코드가 작동을 멈췄을 때 문제가 된다.

상속된 규약

클래스를 상속하거나 다른 라이브러리의 인터페이스를 구현할 때는 규약을 반드시 지켜야 한다. 만약 규약을 지키지 않는다면 제대로 동작하지 않을 수 있다.

class Id(val id: Int) {
	override fun equals(other: Any?) = other is Id && other.id == id
}

val set = mutableSetOf(Id(1))
set.add(Id(1))
set.add(Id(1))
print(set.size) // 3

위 코드처럼 Set는 중복을 허용하지 않는데 equals가 제대로 구현되지 않아서 중복이 허용된다.

참고로 현재 hashCodeequals 구현에 일관성이 없다.

정리

프로그램을 안정적으로 유지하고 싶다면, 규약을 지키자! 규약을 깰 수 밖에 없다면 잘 문서화하자.

이러한 정보는 코드를 유지하고 관리하는 사람에게 큰 도움이 된다. 그 사람이 몇 년 뒤의 당신이 될 수도 있다는 것을 기억하자..

profile
와니와니와니와니 당근당근

0개의 댓글