인프런 커뮤니티 질문&답변

Joshua Kim님의 프로필 이미지
Joshua Kim

작성한 질문수

코틀린 고급편

8강. lateinit과 lazy()

실무에서 lateinit 이 필요한 경우는 어떤 상황일까요?

작성

·

310

1

항상 좋은 강의 감사합니다! 최태현님 강의덕분에 코틀린으로 전환하고 있는 회사에서 적응하는데에 많은 도움 받고있습니다.

 

이번 질문은 lateinit 을 실무에서 사용하는 상황에 대한 것입니다. lateinit 을 사용하는 시점은, 클래스 인스턴스화 시점과 프로퍼티 초기화 시점을 분리하고 싶을 때라는 것은 이해했습니다.

그런데, 실무에서 저런 경우가 어떤 상황인지 잘 생각이 나지 않습니다.

실무에서 lateinit 을 사용하는 경우, 즉 클래스 인스턴스화 시점과 프로퍼티 초기화 시점이 분리가 필요한 경우는 어떤 경우가 있는지 궁금합니다!

답변 1

3

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요, Joshua Kim님! 좋은 질문 감사드립니다! 😊

 

우선 제가 알고 있기로는 안드로이드에서 lateinit 이라는 키워드를 스프링과 함께 사용할 때보다 자주 쓰는 것으로 알고 있습니다. 아무래도 클라이언트 이다 보니, 화면은 유저에게 보여지고 있지만 (즉 화면을 나타내는 클래스는 인스턴스화 되어 사용되고 있지만) 화면에 보여야 하는 데이터 중 일부가 아직 보이고 있지 않은 경우 (클래스의 프로퍼티는 아직 초기화되지 않은) 경우가 꽤 많거든요!

 

반면, 스프링과 코틀린을 함께 사용하는 서버에서는 lateinit 이라는 키워드를 자주 사용하지 않습니다. 제가 경험해봤을 때 lateinit 이 쓰이는 경우는 DI 과정에서 특정 객체 간의 의존성을 더 느슨하게 하고 싶은 경우 였어요! 예를 들어, 우리가 A 객체를 사용하는 B 객체를 만들면 다음과 같이 만들곤 합니다.

@Service
class BService(
  private val aService: Aservice
)

이렇게 되면, 스프링 컨테이너는 생성자를 통해 의존성을 주입하게 되고 따라서 BService를 인스턴스화 하는 시점에 AService가 반드시 존재해야만 하죠. 테스트를 위해 AService에 Stub 객체를 넣기도 애매할 수 있고요.

 

하지만 만약에, AService가 없어도 스프링 컨테이너가 정상적으로 동작하고, 단지 aService를 정말 쓰려고 할 때 에러가 나게 하고 싶다면, lateinit을 활용해 의존성을 설정해줄 수 있습니다.

@Service
class BService {
  lateinit var aService: ASerice
}

또한 이런 경우, BService에 대한 테스트를 작성할 때 AService 인터페이스의 테스트용 구현체를 끼워넣어 테스트를 용이하게 설계할 수도 있습니다.

 

이 외에 (서버 개발자 입장에서) 도메인 모델을 설계하거나, 비즈니스 로직을 작성할 때는 lateinit 키워드를 자주 사용하지는 않았던 것 같습니다. 답변이 도움이 되었으면 좋겠습니다~ 🙏 감사합니다!!! 🙇🙇

 

Joshua Kim님의 프로필 이미지
Joshua Kim

작성한 질문수

질문하기