inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)

companion object사용에 관하여 + entity class의 올바른 메서드 사용

602

jieun ha

작성한 질문수 1

1

안녕하세요. 우선 양질의 kotlin과 jpa관련 강의제공해주셔서 감사합니다.

덕분에 어느정도 갈피를 잡을 수있었어요.

어설픈 질문이지 않을까 걱정도 되지만, 조심스레 여쭤봅니다.

[21강에 사용되는 companion object 의 fun fixture]

해당 메소드는 객체가 생성될때 기본값을 가지도록 되어있는데 해당방식은 실제 프러덕션코드 에서도 적용할 수 있는 방식일까요?

만약 그렇다면 다음과같이 직접적으로 field의 초기값을 설정하는것과 어떻게다른지 궁금합니다.

@Entity
class Book(
  val name: String = "",

  @Enumerated(EnumType.STRING)
  val type: BookType = BookType.COMPUTER,

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  val id: Long? = null,
) {

  init {
    if (name.isBlank()) {
      throw IllegalArgumentException("이름은 비어 있을 수 없습니다")
    }
 }

  fun generateIntegrateName(): String {
    return type.toString() + name
  }

  companion object {
    fun fixture(
      name: String = "책 이름",
      type: BookType = BookType.COMPUTER,
      id: Long? = null,
    ): Book {
      return Book(
        name = name,
        type = type,
        id = id,
      )
    }
  }
}

만약 test를 위해서만 존재하는 코드라면, entity class안에 test만을 위한코드가 존재하는게 자연스러운 구조인가요?

[entity와 관련된 값 구성 강제하기]

entity filed에는 정의되지 않아 Database에 column으로존재하진않지만, dto로 반환하는 integrateName의 생성을 강제하고 싶을때는 위코드의 fun generateIntegrateName 을 entity에 구성하여 dto에서 사용되는것이 올바른 방법인지 궁금합니다.

data class BookInfoResponse(
    val integrateName: String,
) {
    companion object {
        fun of(entity: Book): BookInfoResponse {
            return BookInfoResponse(
                integrateName = entity.generateIntegrateName()
            )
        }
    }
}
val book = bookRepository.findByName("이상한 나라의 엘리스")
    ?: throw IllegalArgumentException("잘못된 요청값입니다.")
val result = BookInfoResponse.of(entity = book).integrateName

강의내용과 검색등의내용을 짜집기해서 사용해보고있는데 막상 구현을하고 보니 적절한 방법인지 알길이 없어서 고민하다 질문드립니다.

시간 내어주셔서 감사드립니다.

kotlin spring-boot 리팩토링

답변 1

1

최태현

안녕하세요, jieun ha님! 좋은 질문 주셔서 감사드립니다. 😊 하나씩 답변 드려 보겠습니다.

 

[fun fixture 관련]

  • 해당 메소드는 객체가 생성될때 기본값을 가지도록 되어있는데 해당방식은 실제 프러덕션코드 에서도 적용할 수 있는 방식일까요?

네 맞습니다, fixture 함수는 객체가 생성될 때 기본값을 갖도록 되어 있습니다. (default parameter라고 불리죠!) 말씀해주신 "프로덕션 코드"가 테스트 코드 / 프로덕션 코드를 구분할 때 쓰는 의미인지, 아니면 프로덕션 레벨의 코드라는 의미의 "프로덕션 코드"인지 정확하지는 않지만, 어떤 경우건 이런 방식은 꽤 자주 사용되는 방식입니다.

실제 자바에서 메소드 오버로드 기능이 있는 것도, 특정 함수를 부를 때 (= 혹은 특정 객체를 만들 때) 특정 파라미터에 대한 기본값을 설정하기 위함 중 하나입니다.

 

  • 만약 그렇다면 다음과 같이 직접적으로 field의 초기값을 설정하는것과 어떻게다른지 궁금합니다.

이 부분은 말씀해주신 "다음"이 정확히 어떤 부분인지 한 번더 알려주시면 답변드릴 수 있을 것 같습니다 😭 비교 대상의 두 코드를 알려주시면 바로 답변드릴 수 있도록 하겠습니다!

 

  • 만약 test를 위해서만 존재하는 코드라면, entity class안에 test만을 위한코드가 존재하는게 자연스러운 구조인가요?

아~~ 좋은 질문이신데요! 이 부분은 살짝 애매합니다! 개발자 분에 따라서는 entity class 안에 테스트용 코드를 두는 것을 싫어하시는 분도 계시고, 크게 상관하지 않는 분도 계십니다. 결국 테스트를 위해 객체 생성을 해야 하는데, 객체 생성 함수를 어디에 둘 것인가에 관한 문제이죠. 저는 개인적으로 크게 상관하지는 않고 어떤 방식이건 통일된 방식이 적용되어 있으면 좋다~ 라고 생각하는 편입니다.

 

[entity와 관련된 값 구성 강제하기]

와우!! 잘 하셨습니다~ 😊

fun generateIntegrateName(): String {
  return type.toString() + name
}

물론 이 함수가 DTO에 있어야 할지 / Entity에 있어야 할지는 목적이나 상황에 따라 달라질 수 있지만, 해당 함수가 여러 DTO에서 재활용되거나, 비즈니스적인 의미가 있다면 충분히 Entity에 들어가도 괜찮습니다.

 

추가로, Kotlin에서는 위와 같은 경우 함수 대신 프로퍼티를 사용할 수도 있습니다.

val integrateName: String
  get() = type.toString() + name

 

또한, (Java이건, Kotlin이건) Enum을 사용하실 때는 name 이라는 프로퍼티를 더 적극적으로 사용하셔도 좋습니다. 😊

val integrateName: String
  get() = type.name + name

 

답변이 도움이 되었으면 좋겠습니다. 감사합니다!! 🙇

안녕하세요 혹시 프론트 코드 제공받을 수 있을까요?

0

69

2

실행이 안되네요

0

67

2

프론트 영역 보는법

0

52

2

companion object

0

79

2

Custom 레프직토리 형식

0

60

2

Querydsl 도입

0

68

2

fetch join DISTINCT 중복제거

1

84

2

표준 예외와 커스텀 예외 사용 전략 질문

0

92

3

이 질문이 왜 없는지 이해가 안 되지만 문제 인식 및 해결 방법 남깁니다.

1

177

2

테스트를 위한 코드

1

105

2

프로젝트 실행 에러

0

153

2

PDF 문서에 오타가 있어서 알려드립니다.

1

102

1

enum질문

1

86

1

테스트 후 AfterEach 함수에서 나오는 쿼리

0

136

2

테스트 fixture

1

211

2

./gradlew test 실행시 인식할수 없다고 뜹니다.

0

141

1

test 코드 실행시 경고가 발생합니다.

0

141

1

13강 User Kotlin 변환중

2

170

3

'추가 - 코프링과 플러그인' 강의 7:46 allopen 관련 질문

2

174

1

-

0

141

2

4:28 build.gradle 수정 시 kotlin-reflect관련 implementation 추가 해야할까요?

0

314

3

junit import 불가

0

276

3

테스트 코드와 관련하여 질문이 있습니다.

1

219

1

hibernate가 select를 두번 하는 이유

0

240

1