LY Corporation Tech Blog

LY Corporation과 LY Corporation Group(LINE Plus, LINE Taiwan and LINE Vietnam)의 기술과 개발 문화를 알립니다.

This post is also available in the following languages. Japanese, English

코드 품질 개선 기법 15편: 문법은 이름을 나타낸다

이 글은 2024년 2월 29일에 일본어로 먼저 발행된 기사를 번역한 글입니다.

안녕하세요. 커뮤니케이션 앱 LINE의 모바일 클라이언트를 개발하고 있는 Ishikawa입니다.

저희 회사는 높은 개발 생산성을 유지하기 위해 코드 품질 및 개발 문화 개선에 힘쓰고 있습니다. 이를 위해 다양한 노력을 하고 있는데요. 그중 하나가 Review Committee 활동입니다.

Review Committee에서는 머지된 코드를 다시 리뷰해 리뷰어와 작성자에게 피드백을 주고, 리뷰하면서 얻은 지식과 인사이트를 Weekly Report라는 이름으로 매주 공유하고 있습니다. 이 Weekly Report 중 일반적으로 널리 적용할 수 있는 주제를 골라 블로그에 코드 품질 개선 기법 시리즈를 연재하고 있습니다.

이번에 블로그로 공유할 Weekly Report의 제목은 '문법은 이름을 나타낸다'입니다.

문법은 이름을 나타낸다

다음 SettingRepository는 어떤 서비스의 사용자 설정을 조회하거나 저장하기 위한 클래스입니다.

class SettingRepository {

    fun getCurrentAccountModel(): QueryResult<AccountModel> {
        ...
    }

    fun deleteCurrentUserAccount(): QueryResult<Unit> {
        ...
    }

    ...
}

이 설정의 기능이 점차 확장돼 SettingRepository에 포함되는 메서드도 증가했다고 가정해 봅시다. 화면마다 다른 설정 항목을 사용한다면 설정 유형별로 클래스를 분리하는 것이 바람직할 수도 있습니다. 예를 들어 Account, Security, Notification, Language 등 설정 항목별로 나누는 것을 생각해 볼 수 있습니다.

분할할 클래스 이름을 어떻게 지을 것인가에 대해 다음 두 가지 방식을 고려하고 있다고 가정해 봅시다. 하나는 Account 등의 수식어를 앞에 붙이는 명명법이고, 다른 하나는 뒤에 붙이는 명명법입니다.

// As a prefix
class AccountSettingRepository { ... }
class SecuritySettingRepository { ... }
class NotificationSettingRepository { ... }
class LanguageSettingRepository { ... }
// As a postfix
class SettingRepositoryAccount { ... }
class SettingRepositorySecurity { ... }
class SettingRepositoryNotification { ... }
class SettingRepositoryLanguage { ... }

이 중 어떤 방식이 더 바람직할까요? 그리고 그 이유는 무엇일까요?

겉모습에 현혹되지 않기

수식어를 뒤에 붙이는 것이 통일감 있고 보기 좋다고 생각할 수 있지만, 수식어는 앞에 붙이는 것이 더 바람직합니다. 해당 클래스를 사용하는 입장에서는 표면적인 일관성보다 문법이 더 중요하기 때문입니다.

물론 수식어를 뒤에 붙이더라도 선언과 정의가 충분히 가깝다면 이름에서 공통된 부분이 명확하기 때문에 이 클래스가 Repository라는 것을 쉽게 알 수 있습니다.

class SettingRepositoryAccount { ... }
class SettingRepositorySecurity { ... }

하지만 이 클래스를 사용하는 측에서는 항상 여러 개의 Repository를 사용하는 것은 아닙니다. 다음과 같이 하나만 사용할 수도 있습니다. 

class CallerClass(
    val environment: Environment,
    val settingRepositorySecurity: SettingRepositorySecurity,
    val dispatcher: Dispatcher
) { ... }

이런 상황에서 Repository에 대한 지식이 없는 개발자가 CallerClass의 코드를 읽는다면 SettingRepositorySecurity를 영문법에 따라 번역해 'SettingRepository의 보안 모듈'로 오해할 수 있습니다. 이런 오해는 코드를 읽는 속도에 상당한 영향을 미칩니다.

반면에 수식어를 앞에 붙이는 명명법은 문법적으로 정확하고 오해의 소지를 줄일 수 있습니다.

class CallerClass(
    val environment: Environment,
    val securitySettingRepository: SecuritySettingRepository,
    val dispatcher: Dispatcher
) { ... }

이름을 지을 때는 '선언하고 정의하는 측에서 보기 좋은지'보다 '사용하는 측에서 오해할 가능성이 적은지'에 초점을 맞춰야 합니다.

수식어 샌드위치

원칙적으로는 수식어를 앞에 두는 것이 좋지만 항상 그렇게 할 수 있는 것은 아닙니다. 다음과 같은 변수를 만든다고 가정해 봅시다.

  • 세로 모드에서 '전송' 버튼의 높이

이 변수에 portraitSendButtonHeightsendButtonPortraitHeight 등의 이름을 붙이면 오해를 불러일으킬 수 있습니다. 예를 들어 portraitSendButtonHeight는 "height of button to send 'portrait'", 즉 '세로 이미지를 전송하는 버튼의 높이'로 읽힐 수 있습니다.

수식어가 둘 이상 필요한 경우 그 중 하나는 맨 뒤에 둬야 할 수도 있습니다. 명사로 수식하는 경우에는 "of", "for", "at", "on", "in"과 같은 전치사를 사용해서 마지막 부분이 수식어구임을 명시해야 합니다. 위 예시에서는 sendButtonHeightForPortrait와 같은 이름이 후보가 될 수 있습니다.

전치사와 관련해서는 두 가지 보충 사항이 있습니다.

  • 보충 사항 1
    • 전치사를 사용해서 맨 뒤에 수식어를 붙이는 것은 변수명 등에서는 허용되는 경우가 많지만 classstruct와 같은 타입 이름을 지을 때는 피하는 것이 좋습니다. 인스턴스 이름은 일반적으로 타입 이름에서 가장 중요한 단어를 뽑아서 명명하는데 이때 마지막 단어를 그대로 사용해 버릴 수 있기 때문입니다.
  • 보충 사항 2
    • 프로그래밍 언어나 플랫폼에 따라 오해의 소지가 적은 경우 전치사를 생략할 수 있습니다. 예를 들어 Java나 Kotlin의 표준 API에서는 "current time in milliseconds"(밀리초 단위의 현재 시각)의 In을 생략하고 currentTimeMillis라는 이름을 사용합니다. 따라서 기존과 비슷한 함수나 변수를 만들 때는 해당 언어와 플랫폼의 표준 명명 규칙을 따르는 것이 바람직합니다.

한 줄 요약: 이름을 지을 때는 선언하고 정의하는 측의 일관성보다 사용하는 측에서 오해할 가능성이 적은지에 중점을 둔다.

키워드: naming, grammar, attributive phrase