정글에서 온 개발자

리플렉션 개념과 도입 기준 본문

TIL

리플렉션 개념과 도입 기준

dev-diver 2024. 12. 7. 11:21

공부 동기

쿼리를 통해 나온 결과를 엑셀 파일로 제공하는 기능을 개발하던 중, 일반화 프로그래밍을 위해 쿼리로 가져온 값을 배열로 일반화해야 했다.  GPT는 go 리플렉션을 추천했는데 이전부터 공부하고 싶던 주제라 찾아봤다.

리플렉션이란?

  • 프로그램 실행 중(런타임)에 자기 자신의 구조와 동작(클래스, 메서드, 속성)을 검사하거나 수정할 수 있는 능력
  • 동적으로 코드를 조작할 수 있음
  • 요약하면 객체의 메타적인 정보를 다루게 해준다

사용되는 주요 사례

  • 프레임워크와 라이브러리
  • JSON, XML 등 데이터 직렬화
  • 테스트 코드

단점

  • 성능 저하 - 런타임에 메소드, 필드에 접근하기 위한 추가적 처리가 필요하기 때문
  • 코드 가독성 떨어짐
  • 예상치 못한 동작 - private 메서드 등에도 접근 가능하기 때문

지원 언어

  • 자바, C#, 파이썬, 자바스크립트, go 등

Go 예시 코드

  • 아래 함수는 객체를 인수로 받아서, 해당 객체에 포함된 '메서드 이름' 을 출력할 수 있음
  • 리플렉션은 이와 같이 코드의 메타적인 정보를 다룬다.
func inspectType(obj interface{}) {
	objType := reflect.TypeOf(obj)
	fmt.Printf("Type: %s\n", objType)
	for i := 0; i < objType.NumMethod(); i++ {
		method := objType.Method(i)
		fmt.Printf("- Method Name: %s\n", method.Name)
	}
	fmt.Println()

}

* 이를 활용하면 특정 메소드 이름을 가진 객체에 대해 로직을 분기할  있다.

개발 중 도입 고려와 최종 결정

  • 서버(go로 작성)에서 Excel 파일을 만드는 함수를 일반화 하기 위하여 조사하던 중 도입을 검토
  • '다양한' map 데이터를 전처리하여 엑셀의 각 행에 입력하는 부분에서 SQL로 가져온 데이터 전체를 reflection 객체로 만들려고 했음
  • 그러나 코드가 필요 이상으로 복잡해지고 성능저하가 예상됨
  • 각 열에 들어가는 값들은 원본 map 데이터들의 조합으로 이루어져, 전처리하는데에 로직마다 커스텀 함수가 필요함
  • 로직마다 커스텀이 들어가면 데이터 구조를 알고 있는 것이기 때문에, reflect 대신 assert를 통한 데이터 형 확인만 거친 후 커스텀 하기로 결정

내가 생각한 도입 기준

  • 컴파일할 때 타입을 알 수 없는가? -> 어떻게든 타입을 미리 알 수 있다면 리플렉션을 쓰지 않는 것이 좋다.
  • 이것은 프레임워크 개발이나, 직렬화, API 개발 등 작성한 프로그램의 활용자가 어떤 형태의 데이터를 보낼지 모르는 경우와 일치하는 기준이다.
  • 프레임워크나 외부통신이 아니라 같이 컴파일되는 코드에서의 활용이라면 리플렉션을 사용할 일이 거의 없을 것 같다.

참고 자료

https://f-lab.kr/insight/understanding-java-reflection