Skip to content

코드 리뷰로부터 시작된 제네릭 타입 네이밍 컨벤션 지정

Seogeurim edited this page Dec 17, 2021 · 5 revisions
  • 작성자: @Yunseo Hwang
  • 작성일: 2021.12.14
  • Description: 제네릭 타입 네이밍 컨벤션을 정하게 된 배경에 대해서 정리합니당.

논의 배경

async get<R = unknown, D = unknown>(
  config?: ApiRequestConfig<D>,
): Promise<HTTPResponse<R>> {
  const url = `${this.apiUrl}${config?.additionalUri ?? ''}`;

  const request = () => this.client.get<R, D>(url, config);

  return this.requestWithSilentRefresh<R>(request);
}

그림님께서 위 코드에 대해서 아래와 같이 리뷰를 남기면서 제네릭 타입 네이밍을 어떻게 하는 것이 좋을 지에 대한 의논을 시작했습니다.

R, D와 같이 타입을 나타내기보다 ResponseType, DataType(?) 등 좀 더 알기 쉬운 이름으로 바꾸는 것은 어떤가요?

저는 윤서님이 짜신 코드를 보면서 생소하니, R, D 타입을 보면서 Request? Response? D? Data? 이러면서 다른 코드를 읽으면서 어떤 의미인지 찾아가게 되더라구요!!

논의 전개

정확한 논의 내용을 확인하시려면 telbby-frontend의 #48 PR 리뷰 내용을 확인해주세요

1. R, D와 같이 애매모호한 네이밍 대신 ResponseType, DataType과 같은 구체적인 네이밍을 사용하자

제안자: Seogeurim

개요 및 배경

R, D와 같은 네이밍은 처음 코드를 살펴보는 입장에서 코드의 내부를 보지 않으면 해당 타입이 어떤 역할을 하는 지 알 수 없다는 문제점이 있습니다.

그래서 ResponseType, DataType과 같이 더 구체적인 네이밍을 사용하는 것을 그림님께서 제안하셨습니다.

리뷰 원문:

서그림:

R, D와 같이 타입을 나타내기보다 ResponseType, DataType(?) 등 좀 더 알기 쉬운 이름으로 바꾸는 것은 어떤가요?

문제점

제안자: Yunseo Hwang

일반적으로 제네릭 타입 지정을 사용한 코드를 살펴봤을 때 영문 약자를 사용하는 게 마음에 걸렸습니다.

리뷰 원문:

황윤서:

요상하게 제네릭 타입을 사용한 코드들을 보면 약자들을 사용하더라고요.

저 R, D라는 것도 사실 axios 라이브러리에서 가져온 건데... 타이핑 양 때문에 주로 약자를 사용하는 게 아닐까 싶습니다

2. default type을 type alias를 통해 네이밍하여 의도를 전달하자.

제안자: Yunseo Hwang

개요 및 배경

요건 default type 지정하는 부분을 제약 조건 지정으로 착각하여 제안했다는 사소한 문제가 있지만 의도 자체는 네이밍 자체를 유지하면서 의미를 전달하겠다라는 거였습니다.

type ResponseType = unknown;
type DataType= unknown;

async get<R = ResponseType, D = DataType>( /* ... */) { /* .... */};

리뷰 원문:

황윤서:

그래서 고민을 좀 해봤는 데, 제안해주신 근본적인 의도를 생각해보면 R, D라는 제네릭 타입이 뭘 의미하는 지 더 명확하게 파악할 수 있으면 좋겠다`인 것 같습니다.

그러면 제네릭 타입의 제약조건으로 걸어주고 있는 unknown을 별도의 타입으로 선언하여 그 네이밍으로써 의미를 전달하면 어떨까요?

요걸로도 충분히 코드를 보지 않고 각 제네릭 타입이 뭘 의미하는 지 파악할 수 있지 않을까 싶습니다.

=> 제가 파악한 근본적인 의도가 잘못되었다면 말씀해주세요!

문제점

제안자: Seogeurim

default type을 지정해주는 부분이고 unknown 타입에 대해 type alias 해주는 게 의미가 없는 것처럼 느껴집니다.

리뷰 원문:

서그림:

R, D 부분은 근본적인 의도가 그게 맞습니다!!

저는 윤서님이 짜신 코드를 보면서 생소하니, R, D 타입을 보면서 Request? Response? D? Data? 이러면서 다른 코드를 읽으면서 어떤 의미인지 찾아가게 되더라구요!!

그런데 unknown 타입에 대해 ResponseType, DataType을 지정해서 넣어주는 것은 과연 맞을까, 의문이 듭니다!!

타이핑 양이 많아지더라도 이 부분은 모듈이라 다른 곳에서 타이핑을 할 일이 없으니 괜찮지 않을까 조심스레 의견 남겨봅니다!!

서그림:

의문이 들었던 이유는, 디폴트 타입을 지정해주는 부분인데 unknown으로서 크게 의미가 없는 타입이다보니 그렇게 지정하는 것이 맞을까 했던 것입니다!!

하지만 개발자는 우리이니 ㅎㅎ 타이핑 양이나 이런 부분을 생각했을 때 컨벤션으로서 지정해주는 것도 좋을 것 같아요!

다른 분들 의견도 궁금한데, 이 부분 윤서님 마음 가는대로 한번 해보시죠 !!! ㅎㅎㅎ

3. 구체적인 네이밍을 사용하되 T suffix를 사용하자

제안자: Yunseo Hwang

개요 및 배경

그림님께서 마음 가는대로 해보라고는 했지만 뭔가 마음에 걸렸기 때문에 확신을 얻기 위해 우선 자료를 조사했습니다.

요상하게 제네릭 타입을 사용한 코드들을 보면 약자들을 사용하더라고요.

가장 먼저 요 이유를 파악하기 위해서 제네릭 타입에 있어서 네이밍 컨벤션이 있는 지를 찾아봤습니다.

찾아본 결과, 제네릭이 C#이나 자바로부터 왔고 해당 언어에서 단일 영대문자를 사용하는 것이 관행적인 네이밍 컨벤션이었기 떄문이다라는 결론을 얻었습니다.

그리고 단일 영대문자를 사용하는 것은 인터페이스나 Type alias와 구분해주기 위해서였습니다.

image

그렇지만 T, K, V, 등의 일반적으로 많이 사용되는 네이밍을 사용하지 않을 경우, 해당 네이밍을 사용하더라도 그 네이밍이 그 역할을 모두 전달할 수 없을 경우 문제가 발생할 가능성이 있었습니다. 그림님이 처음에 언급하신 대로 코드를 보지 않고서는 의미를 파악하기 어려울 수 있었습니다.

찾아보니 다른 많은 사람들도 이것에 대해서 인식하고 의논하고 있었습니다. Naming Conventions for Parameterized Types의 Comment들을 확인해보면 아래와 같은 대체 네이밍들을 각자 사용하고 있는 것을 확인할 수 있었습니다.

  • $ prefix 사용
  • T prefix 사용
  • Type suffix 사용
  • 전부 대문자 사용
  • T_ prefix 사용
  • 이외 등등

요런 것들을 확인했을 때 너무 중구난방인 것 같았기 때문에 더 많이 사용되고 있는 대체 컨벤션은 없는 지 찾아보았습니다.

image

구글 자바 스타일 가이드(요 글을 통해 첨 알게 되었습니다.)를 확인해보면 T suffix를 사용하는 방식을 채택하고 있었습니다.

이 방식은 더 구체적인 의미를 담은 네이밍을 가능하게 하면서도 인터페이스&Type alias와 구분할 수 있었고, 구글이라는 빅테크 기업이 제공하는 가이드인 만큼 많은 곳에서 사용하고 있는 방식이라고 판단했습니다. 비록 다른 언어의 스타일 가이드이지만 제네릭 자체가 자바, C#에서 온 만큼 채택해도 괜찮다고 생각했습니다.

논의 결과

결과적으로 위와 같은 논의 과정과 자료 조사 과정을 거쳐서 구체적인 네이밍을 사용하되 T suffix를 사용하자라는 컨벤션을 지정하게 되었습니다.

개인적인 관점에서 논의를 평가했을 때 처음에 그림님께서 제안을 해주셨고 요상하게 영문 약자를 많이 사용하는 것 같다라는 의문이 들었을 때 자료들을 조사한 후에 Comment를 달았으면 더 효율적인 논의가 이뤄졌지 않았을까 하는 마음에 약간 아쉬운 감이 있네요.


댓글

  • 서그림 : 윤서님께서 이렇게 자세히 정리해주시니,,,, 제가 또 감명을 받고 갑니다 🤩 저도 먼저 자료를 조사하고 comment를 달걸 하는 아쉬움이 남았었는데, 똑같은 생각이었군요!! 무튼 이런 토론을 통해 경험을 쌓아나가는 것 참 좋네요 ㅎㅎㅎ
Clone this wiki locally