|
| 1 | +# 32. 추상화 규약을 지켜라 |
| 2 | + |
| 3 | +--- |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +# 개요 |
| 8 | + |
| 9 | +규약은 개발자들의 단순한 합의임 |
| 10 | + |
| 11 | +→ 따라서 한쪽에서 규약을 위반할 수도 있고, 기술적으로 모든 부분에서 규약 위반이 발생할 수 있음 |
| 12 | + |
| 13 | +다음과 같이 리플렉션을 활용하면 우리가 원하는 것을 열고 사용할 수 있음 |
| 14 | + |
| 15 | +```kotlin |
| 16 | +class Employee { |
| 17 | + private val id: Int = 2 |
| 18 | + override fun toString() = "User(id=$id)" |
| 19 | + |
| 20 | + private fun privateFunction() { |
| 21 | + println("Private function called") |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | +fun callPrivateFunction(employee: Employee) { |
| 26 | + employee::class.declaredMemberFunctions |
| 27 | + .first{ it.name = "privateFunction" } |
| 28 | + .apply { isAccessible = true } |
| 29 | + .set(employee, newId) |
| 30 | +} |
| 31 | + |
| 32 | +fun changeEmployeeId(employee: Employee, newId: Int) { |
| 33 | + employee::class.java.getDeclaredField("id") |
| 34 | + .apply { isAccessible = true } |
| 35 | + .set(employee, newId) |
| 36 | +} |
| 37 | + |
| 38 | +fun main() { |
| 39 | + val employee = Employee() |
| 40 | + callPrivateFunction(employee) |
| 41 | + // 출력 : Private Function called |
| 42 | + |
| 43 | + changeEmployeeId(employee, 1) |
| 44 | + print(employee) // 출력: User(id=1) |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | +but 무언가를 할 수 있다는 것이 그것을 해도 괜찮다는 의미는 아님 |
| 49 | + |
| 50 | +위 코드는 `private` 프로퍼티와 `private` 함수의 이름과 같은 세부적인 정보에 크게 의존하고 있음 |
| 51 | + |
| 52 | +이러한 이름은 언제든 변경될 수 있음 |
| 53 | + |
| 54 | +따라서 이런 코드를 프로젝트에서 사용한다면, 프로젝트 내부에 시한 폭탄을 설치한 것과 같음 |
| 55 | + |
| 56 | +--- |
| 57 | + |
| 58 | +# 상속된 규약 |
| 59 | + |
| 60 | +클래스를 상속하거나, 다른 라이브러리의 인터페이스를 구현할 때는 규약을 반드시 지켜야 함 |
| 61 | + |
| 62 | +만약 규약을 제대로 지키지 않는다면, 객체가 제대로 동작하지 않을수 있음 |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +# 정리 |
| 67 | + |
| 68 | +- 프로그램을 안정적으로 유지하고 싶다면 규약을 지켜야 함 |
| 69 | +- 규약을 깰 수밖에 없다면, 이를 잘 문서화 해야함 |
| 70 | + |
| 71 | +--- |
0 commit comments