ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kotlin 사용하면서 배운 10가지
    개발하면서/타인글보면서 2024. 1. 30. 09:42
    반응형

    IT 컨설턴트 회사 Xebia에서 Kotlin을 사용하면서 배운 10가지 정리한 글을 읽었다.

    https://xebia.com/blog/using-kotlin-in-a-java-project-10-lessons-learned/

     

    Using Kotlin in a Java project: 10 lessons learned

    Kotlin Using Kotlin in a Java project: 10 lessons learned - Xebia

    xebia.com

     

    Java에서 Kotlin으로 넘어가면서 느낀 장점은

    Null safety와 data class를 이용해서 boilerplate 코드가 눈에 띄게 줄었다는 점이다.

     

    현재 업무로 Kotlin + Spring을 쓰고 있는데 (Java 보다는) 직관적이고 다양한 표현식들이 있어 편하다.

    Java에서 Virtual Thread 얘기가 들리는데 굳이... Java의 장점이 크지 않다면 앞으로 계속 Kotlin을 쓸 것 같다.

    ※ 물론 회사에서 Java 쓴다고 하면 써야지 허허허


     

    0 - Java에서 Kotlin 마이그레이션 전략

    두 가지 방법이 있는데

    IntelliJ의 기능을 사용하는 방법과

    새로운 기능과 새로운 기능과 연결된 코드를 Kotlin으로 작성하는 방법이 있다.

     

    첫 번째

    IntelliJ에서 Code -> Convert Java File to Kotlin File 기능을 사용한다.

     

    두 번째

    해당 프로젝트 전체를 Kotlin으로 다시 작성하는 게 아니라 일부분만 전환하는 걸 목표로 진행하는 방법이다.

    hexagonal architecture를 적용한 프로젝트인 경우

    핵심 비즈니스 로직을 Kotlin으로 작성하고 외부 코드는 Java로 유지하는 식이다.

    https://medium.com/@luishrsoares/whats-hexagonal-architecture-6da22d4ab600

     

     

    1 - Kotlin과 Java 파일이 한 프로젝트에 공존

    src/main/java, src/main/kotlin 으로 분리해서 하지 말고

    같은 package에서 Kotlin과 Java 코드를 위치시켜도 된다.

     

    2 - Kotlin에서 nullable 한 Java 코드 호출

    두 가지 방법이 있다.

     

    첫 번째

    null을 리턴하는 method 위에 `org.jetbrains.annotations.Nullable` annotation을 붙인다.

     

    두 번째

    Java method의 결과를 Kotlin의 변수에 할당하는데 이때 변수 타입을 nullable임을 명시한다.

     

    3 - Kotlin에서 Lombok 지원은 불안정

    $> ./gradle build -dry-run을 실행하면 어떤 순서로 빌드가 실행되는지 볼 수 있는데

    compileKotlin이 compileJava 앞에 나온다.

    compileKotlin은 Lombok annotation이 적용된 JVM 바이트코드가 필요한데

    아직 compileJava가 실행 전이라 JVM 바이트 코드가 준비되지 않아 의도한 대로 동작하지 않는다.

     

    해결하는 방법은

    @Getter Lombok annotation이 있다면 getter method를 명시적으로 써주거나

    Kotlin Lombok Plugin 또는 Kapt 를 사용한다.

    가장 깔끔한 방법은 Lombok이 적용된 Java 파일을 Kotlin data class로 전환하는 방법이다. ㅎㅎ

     

    4 - 빌더 대신 생성자 사용

    Lombok의 @Builder 대신 Kotlin 생성자를 이용하자.

    멤버변수가 많다면 Kotlin Fill Class Plugin을 사용하면 도움이 된다.

     

    단위 테스트 작성할 때 멤버 변수가 많다면 생성자를 채우는 게 굉장히 번거롭다.

    테스트 검증을 위해 일부만 채우고 나머지는 dummy로 채워도 괜찮은 경우가 많은데 이때 mokk 사용을 추천한다.

     

    예를 들어 주문의 uid와 주문 항목의 상품코드와 수량만 테스트에 사용할 경우 아래처럼 해주면 된다.

    val order = mockk<Order> {
      every { uid } returns "someOrderUid"
      every { entries } returns listOf(
        mockk {
          every { productCode } returns "123456"
          every { quantity } returns 3
        }
      )
    }

     

    카카오 페이 블로그에서도 Java 프로젝트를 Kotlin으로 전환 경험 정리한 글이 있으니 참고하자.

     

    자바 프로젝트 3개 코틀린 점진적 전환기(feat. lombok 됩니다.) | 카카오페이 기술 블로그

    코틀린을 학습하고, 적용하고, 변환해 봤던 이야기와 실제 자바 프로젝트를 변환하는 샘플을 공유합니다.

    tech.kakaopay.com

     

    5 - 코드 포맷팅 표준화를 위한 Kotlin 도구

    Java에서는 Spotless를 이용해서 코드 포맷을 표준화할 수 있는데 Kotlin도 지원하지만 몇 가지 제약사항이 있다.

    그래서 Spotless와 비슷한 기능을 제공하는 ktlint 사용을 추천한다.

    커밋 전에 ktlinFormat 명령어를 실행시키고 CI/CD에서 빌드하는 동안 ktlintCheck 실행하도록 수정하면 된다.

     

    6 - 클래스 직렬화/역직렬화

    Kotlin에서 Jackson을 사용해서 JSON 직렬화/역직렬화를 할 수 있지만
    Kotlin 전용 Kotlin Serialization 프레임워크도 사용도 고려해 보자.

    Jackson과 동일한 기능을 제공하고 추가 장점으로는

    Sealed class와 호환성을 가져서 패턴매칭이 가능하다는 점이다.

     

    한 가지 주의할 점 역직렬화하는 코드가 Kotlin Serialization 를 사용하지 않으면

    타입 처리 방법을 자동으로 알지 못한다.

    ※ 너무나 큰 주의점이다;;

     

    7 - 타입 별칭 사용

    method의 parameter나 리턴의 타입이 Map<Stirng, List<Long> 인 경우도 있다.

    이때 Map<Stirng, List<Long>가 뭘 뜻하는지 이해하기 어려운데 별칭을 사용해 용도를 명확하게 할 수 있다.

    typealias SomeMeaningfulTypeName = Map<String, List<Long>>

     

     

    8 - 테스트 코드에서 assert 자연스럽게 표현하기

    문장을 읽는 것처럼 표현이 가능하다.

    // before
    assertThat(actual).isEqualTo(expected)
    assertEquals(expected, actual)
    
    // kotlin 직관적인 표현
    actual shouldBe expected

     

    shouldBe로 표현할 수 있는 이유는 Kotlin의 infix notation을 사용했기 때문이다.

    shouldBe 뿐만 아니라 shouldNotBe, shouldBeNull도 infix notation을 사용하여 표현할 수 있다.

     

    9 - Coroutine 사용

    계산이 많지 않고 다양한 서비스를 호출하고 결과를 기다린 후 조합하는 Application이 있을 수 있다.

    해당 Application을 Kotlin으로 작성한다면 Coroutine 사용을 추천한다.

    약간의 학습곡선이 있지만 한번 진득하게 배워두면 굉장히 읽기 쉬운 동시성 코드를 짤 수 있다.

    반응형

    댓글

Designed by Tistory.