이 책의 저자가 생각하는 프로그래밍의 가장 큰 규칙은 아래와 같다.
프로젝트에서 이미 있던 코드를 복사해서 붙여넣고 있다면, 무언가가 잘못된 것이다.
이번 챕터의 제목인 'knowledge를 반복하여 사용하지 말라'는 위의 내용을 저자의 방식으로 표현한 것이다.
위 규칙은 DRY 규칙, WET 안티패턴, SSOT 등으로도 불린다.
위 규칙을 확실하게 적용하려면, 언제 왜 이 이야기가 나오는지 이해해야한다.
knowledge
프로그래밍에서 knowledge 는 넓은 의미로 '의도적 정보'를 뜻한다.
프로젝트를 진행할 때 정의한 모든 것이 knowledge가 될 수 있다.
예를 들어 알고리즘의 작동 방식, UI 형태, 우리가 원하는 결과 등 모두 의도적 정보이자 knowledge 이다.
우리 프로그램에서 중요한 knowledge를 크게 두 가지 뽑는다면, 아래와 같다.
1) 로직(logic): 프로그램이 어떠한 식으로 동작하는지와 프로그램이 어떻게 보이는지
2) 공통 알고리즘(common algorithm): 원하는 동작을 하기 위한 알고리즘
1) 과 2) 사이의 가장 큰 차이점은 무엇일까?
정답은 시간의 변화이다.
비즈니스 로직은 시간이 지나면서 계속 변하지만 공통 알고리즘은 한 번 정의되면 이후 크게 변하지 않는다.
모든 것은 변화한다
프로그래밍에서 유일하게 유지되는 것은 '변화한다는 속성'이라는 말이 있다.
모든 것은 변화하고, 우리는 이에 대비해야 한다. 변화할 때 가장 큰 적은 knowledge가 반복되어 있는 부분이다.
여러 종류의 추상화를 표현할 수 있는 수많은 솔루션이 있으며, 이를 활용하면 반복을 줄일 수 있다.
언제 코드를 반복해도 될까?
이 파트에서는 추출을 통해 knowledge 반복을 줄이면 안 되는 상황을 이야기하고 있다.
예를 들어 독립적인 2개의 안드로이드 프로젝트가 있을 때, 빌드 설정이 비슷할 것이라고 생각하고 이를 추출해서 knowledge 반복을 줄일 수 있다고 볼 수도 있다.
하지만 두 애플리케이션은 독립적이기 때문에 한 쪽의 구성만 변경이 필요할 수도 있을 것이다.
코드를 추출하는 이유는 변경을 쉽게 만들기 위함인데, 위와 같이 신중하지 못한 추출은 변경을 더 어렵게 만든다.
개발자가 결정을 쉽게 하기 위한 유용한 방법을 소개해 주는데, 그 방법은 '비즈니스의 규칙이 다른 곳에서 왔는지 확인'하는 방법이다.
다른 곳에서 왔다면, 독립적으로 변경될 가능성이 높다.
잘못된 코드 추출로부터 우리를 보호할 수 있는 규칙도 있는데, 단일 책임 원칙(Single Responsibillity Principle, SRP) 이다.
단일 책임 원칙
코드를 추출해도 되는지 확인할 수 있는 원칙으로 SOLID 원칙 중 하나인 단일 책임 원칙이 있다.
단일 책임 원칙: 클래스를 변경하는 이유는 단 한가지여야 한다.
만약 서로의 업무와 분야에 대해 잘 모르는 개발자들이 있다고 가정했을 때, 개발자들이 같은 코드를 변경하는 것은 굉장히 위험한 일이다.
책에서 들고 있는 예시를 간단히 설명하자면 아래와 같다.
- 어떤 대학에서 Student 라는 클래스를 가지고 있다.
- 이 클래스는 장학금 관련 부서, 인증 관련 부서에서 사용하고 있다.
- 두 부서에서 해당 클래스에 qualifiesForScholarship (장학금 관련 부서의 프로퍼티), isPassing(인증 관련 부서의 프로퍼티) 프로퍼티를 추가했다.
- 두 프로퍼티는 직전 학기 성적 기반으로 계산되며, 개발자는 두 프로퍼티를 한 번에 계산하는 calculatePointsFromPassedCourses 함수를 만들었다.
- 그런데 요구사항이 변경되어 장학금 관련 프로퍼티에 수정이 필요했고, 해당 역할을 수행 중인 calculatePointsFromPassedCourses 를 수정했다.
- 하지만 이 과정에서 isPassing 가 함께 수정되어 인증 관련 오류가 발생하게 되었다.
만약 StudentIsPassingValidator와 StudentQualifiesForScholarshipValidator 클래스를 구분했다면, 이와 같은 혼선을 막을 수 있었을 것이다.
코틀린의 확장 함수를 활용하면, 두 함수는 Student 클래스 아래에 두면서 동시에 각각의 부서가 관리하는 서로 다른 모듈 파일에 배치할 수도 있다.
// accreditations 모듈
fun Student.qualifiesForScholarshop(): Boolean {
/*...*/
}
// scholarship 모듈
fun Student.calculatePointsFromPassedCourses(): Boolean {
/*...*/
}
추가적으로 두 결과를 계산하는 함수를 만들 수 있다.
다만 헬퍼 함수는 private 함수로 만들지 않고, 아래 두 가지 방법으로 만드는 것이 일반적이다.
1. 두 부서에서 모두 사용하도록 public 함수로 만든다. 하지만 공통 부분은 두 부서에서 모두 사용하므로, 함부로 수정해서는 안된다.
2. 헬퍼 함수를 각각 부서의 모듈에 만든다. (2개)
위 긴 예시에 대한 설명이 말하고자 하는 바는 아래와 같다.
- 서로 다른 곳에서 사용하는 knowledge는 독립적으로 변경할 가능성이 많다. 따라서 비슷한 처리를 하더라도, 완전히 다른 knowledge로 취급하는 것이 좋다.
- 다른 knowledge는 분리해 두는 것이 좋다. 그렇지 않으면, 재사용해서는 안 되는 부분을 재사용하려는 유혹이 발생할 수 있다.
정리
- 공통 knowledg가 있다면, 이를 추출해서 변화에 대비하는 것이 좋다.
- 여러 요소에 비슷한 부분이 있는 경우, 변경이 필요할 때 실수가 발생할 수 있으니 추출하는 것이 좋다.
- 의도하지 않은 수정을 피하려면 또는 다른 곳(부서 등)에서 조작하는 부분이 있다면, 분리해서 사용하는 것이 좋다.
- 정보 시스템 설계는 예술의 영역과 비슷하기 때문에 수많은 시간과 많은 연습이 필요하다.
'Study OR Book > Book' 카테고리의 다른 글
[이펙티브 코틀린] 아이템32: 추상화 규약을 지켜라 (0) | 2025.02.03 |
---|---|
[이펙티브 코틀린] 아이템29: 외부 API를 랩(wrap)해서 사용하라 (0) | 2025.01.21 |
[이펙티브 코틀린] 아이템17: 이름 있는 아규먼트를 사용하라 (0) | 2025.01.08 |
[이펙티브 코틀린] 아이템7: 결과 부족이 발생할 경우 null 또는 Failure를 사용하라 (1) | 2024.12.18 |
[이펙티브 코틀린] 아이템3: 최대한 플랫폼 타입을 사용하지 말라 (1) | 2024.12.11 |