피드로 돌아가기
코드 품질 개선 기법 19편: 차일드 록
LINE Engineering
Backend

코드 품질 개선 기법 19편: 차일드 록

LY Corporation이 MessageListPresenter의 오버라이딩 범위를 제한해 super 호출 누락, 오버라이딩 누락, 책임 범위 혼동으로 인한 버그 3가지 제거

2025년 9월 3일8intermediate

Context

부모 클래스의 bind 메서드를 open으로 선언하고 자식 클래스에서 오버라이딩하도록 설계했을 때, 자식 클래스에서 super.bind()를 명시적으로 호출하지 않으면 헤더와 푸터가 업데이트되지 않는 버그가 발생한다. 또한 오버라이딩이 필수라는 제약이 인라인 주석으로만 표현되어 누락되기 쉬우며, 오버라이딩의 책임 범위가 함수의 책임 범위와 일치하지 않는 문제가 있다.

Technical Solution

  • bind 메서드를 open에서 final(또는 open 수정자 제거)로 변경: 자식 클래스가 전체 흐름을 오버라이딩할 수 없도록 제한
  • updateMessageList라는 별도의 protected abstract 메서드 추출: 헤더/푸터 업데이트와 메시지 목록 업데이트 로직을 분리
  • bind 메서드 내에서 updateHeader, updateFooter, updateMessageList를 순차적으로 호출: 부모 클래스에서 전체 흐름을 제어하고 변경 불가능하게 고정
  • 자식 클래스는 updateMessageList만 오버라이딩: super 호출 없이 자신의 메시지 표시 로직만 구현
  • private 메서드로 헤더/푸터 업데이트 로직 캡슐화: 자식 클래스에서 접근 불가능하게 설정

Key Takeaway

오버라이딩 가능한 함수의 범위를 최대한 제한하고 명시적 super 호출이 필요한 상황을 피해야 한다. Template Method 패턴으로 부모 클래스의 흐름을 final 메서드로 고정하고 자식 클래스는 abstract 메서드만 구현하도록 강제하면 상속 오류를 구조적으로 방지할 수 있다.


Kotlin/Java에서 상속 구조를 설계할 때, 자식 클래스가 오버라이딩할 수 있는 메서드는 추상 메서드(abstract)로 선언하고, 부모 클래스의 흐름 제어는 final 메서드로 작성하면 자식 클래스의 super 호출 누락이나 책임 범위 혼동을 구조적으로 제거할 수 있다.

원문 읽기