코드 품질 개선 기법 11편: 반복되는 호출에 함수도 지친다 (새 탭에서 열림)
객체의 상태를 확인하고 그 결과에 따라 상태를 변경하는 로직은 호출자가 아닌 해당 객체 내부로 캡슐화하는 것이 코드 품질을 높이는 핵심입니다. 이를 통해 외부로 드러나는 상태 전이 로직을 단순화하고, 조건 확인 누락으로 인해 발생할 수 있는 잠재적인 버그를 효과적으로 방지할 수 있습니다. 특히 상태 변경 여부에 따른 후속 작업이 필요할 때는 복잡한 콜백보다 명확한 반환값을 활용하는 것이 코드의 가독성과 유지보수 측면에서 유리합니다.
상태 확인 로직의 내재화
if (receiver.a()) { receiver.b() }와 같이 외부에서 객체의 상태를 묻고 동작을 결정하는 구조는 중복 호출의 번거로움과 확인 누락의 위험을 수반합니다.- 상태를 변경하는 함수(예:
markAsFriend) 내부에서 직접 조건을 검사(예:isFriend)하도록 설계하면, 호출자는 객체의 내부 상태를 일일이 신경 쓰지 않고도 안전하게 기능을 수행할 수 있습니다. - 이러한 방식은 객체 내부의 상태 전이를 단순화하며, '이미 해당 상태인 경우 아무것도 하지 않는다'는 동작을 자연스럽게 보장합니다.
- 만약 조건부 동작임을 명시적으로 드러내야 한다면
markAsFriendIfNotYet과 같이 함수 이름을 명확하게 짓거나 주석으로 보완하는 방법이 권장됩니다.
콜백 대신 반환값으로 결과 전달
- 상태 변경 성공 여부에 따라 팝업 노출과 같은 후속 작업이 필요할 때, 고차 함수를 통한 콜백(onSucceeded) 방식은 피하는 것이 좋습니다.
- 콜백 방식은 의존성 순환을 일으킬 수 있고, 해당 로직이 동기적으로 실행되는지 비동기적으로 실행되는지 호출부에서 파악하기 어렵게 만듭니다.
- 대신
Boolean등의 반환값을 활용하면 호출자가 결과에 따라 후속 로직을 직접 제어할 수 있어 코드의 실행 흐름이 명확해집니다. - 이때 함수 이름에서 반환값의 의미가 명확히 드러나지 않는다면 문서화를 통해 보완하고, 호출자가 반환값을 반드시 확인하도록 강제하는 기법을 함께 사용할 수 있습니다.
객체 설계 시 "묻지 말고 시키라(Tell, Don't Ask)"는 원칙을 적용해 보시기 바랍니다. 객체 외부에서 상태를 묻고 판단하기보다, 객체가 스스로 자신의 상태를 확인하고 동작하게 함으로써 더 견고하고 읽기 쉬운 코드를 작성할 수 있습니다.