공부기록

Kotlin 함수 연속 호출을 보다 가독성있게 바꿔보자 본문

Kotlin

Kotlin 함수 연속 호출을 보다 가독성있게 바꿔보자

gracelove91 2024. 12. 31. 13:17
반응형

일정관리 웹 프로그램을 만들고 있다고 가정하고,
public api 를 통해 "특정 사용자의 특정 카테고리 안에 있는 할 일들을 웹페이지에 렌더링 해줘." 같은 요청을 받았다 가정하자.
요청에는 특정사용자의 이름과 특정 카테고리를 포함한다.
e.g. http://gracelove.kr/todo/{username}/{category}

이런 요청을 받으면 내부적으로 다음과 같은 일을 한다.

  1. user와 category 를 추출한다.
  2. 1에서 추출한 username 과 category 에 해당하는 todo 목록을 가져온다.
  3. 2에서 가져온 todo 목록을 기반으로 html 페이지를 생성한다.
  4. 사용자에게 http 응답을 준다.

이걸 코드로 표현해보자면..


// 요청 엔트리포인트
fun getTodoList(request: Request): Response

// user와 category 를 추출한다.
private fun extractDataFromRequest(request: Request): Pair<User, Category>

// username 과 category 에 해당하는 todo 목록을 가져온다.
private fun fetchTodoContents(data: Pair<User, Category>): List<Content>

// todo 목록을 기반으로 html 페이지를 생성한다.
private fun createHtmlPage(contents: List<Content>): HtmlPage

// 사용자에게 전달할 http 응답을 생성
private fun createResponse(html: HtmlPage): Response

여기서 엔트리포인트인 getTodoList 에서 사용자에게 요청을 받고,
다음과 같은 순서로 함수 호출을 한다.

  1. extractDataFromRequest
  2. fetchTodoContents
  3. createHtmlPage
  4. createResponse

개인적으로 이럴 땐 메서드 하나하나의 응답을 변수에 담아 다음 메서드를 호출할 때 넘겨주지만,
괜히 라인 수를 늘리고 싶지 않은 사람들은 다음과 코드를 작성할 것이다.

fun getTodoList(request: Request): Response {
    return createResponse(
        createHtmlPage(
            fetchTodoContents(
                extractDataFromRequest(
                    request
                )
            )
        )
    )
}

이 코드의 문제점은 뭘까? 가장 큰 문제는 읽기 힘들다! 왜 읽기 힘들까?
사람은 위에서부터 아래로 읽는다. 근데 코드를 자세히보자! 코드가 위에서부터 읽히는가? 아니다. 반대로 읽어야 한다.
가장 먼저 호출될 함수가 가장 안쪽에 있다!

이 정도만 되도 라인 수 늘리고 싶지 않은 사람들도 이쯤되면 포기하고 응답을 변수에 담아 다음 메서드들을 호출할 것이다.
하지만, 포기하지 말자! 라인수를 늘리지 않고, 위에서 아래로 훨씬 가독성있게 고칠 수 있다. 어떻게?

letMethod Reference 을 이용해보자!

letMethod Reference 을 이용한 kotlin 공식홈페이지의 설명과 kotlin playground 링크다.

If the code block passed to let contains a single function with it as an argument, you can use the method reference (::) instead of the lambda argument:
kotlin playground

다음은 기존 코드를 수정한 코드다.

fun getTodoList(request: Request): Response {
    return request
        .let(::extractDataFromRequest)
        .let(::fetchTodoContents)
        .let(::createHtmlPage)
        .let(::createResponse)
}

훨씬 가독성 있게 수정되었다.
하지만, 개인적으로 변수에 담아 함수 파라미터에 직접적으로 넘기는 게 더 가독성이 좋아보인다.

반응형