-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
이전에 스터디에서 잠깐 말씀드린 transformer 를 최근에 적용해 보아서 간단하게 공유 드려 봅니다!
보통 컨트롤러에서 서비스에게 SomeResponse 라는 타입이 필요하면 서비스 메서드의 반환 타입으로 고정시켜 구현을 하는데요.
def search(someRequest : SomeRequest) : SomeResponse = {
val someEntity : SomeEntity = someRepository.find(someRequest)
return SomeResponse(SomeEntity)
}
대충 위 같은 형식이 되겠죠?
위 같은 경우에 만약 컨트롤러가 SomeResponse 라는 타입이 아니라 다른 타입을 원하게 되면 컨트롤러, 서비스의 로직이 변경되어야 하겠죠.
하지만 transformer 를 이용하면 컨트롤러 단에서만 반환값의 타입을 제어할 수 있었습니다.
def search[T](someRequest : SomeRequest, transformer : SomeEntity => T) : T = {
val someEntity : SomeEntity = someRepository.find(someRequest)
return transformer(someEntity)
}
이걸 컨트롤러에서 사용하면
// SomeResponse 를 반환받고 싶다면
search(someRequest = someRequest , transformer = { SomeEntity => return SomeResponse()})
// 처럼 람다 함수로 transformer 를 넘겨주거나
search(someRequest = someRequest , transformer = SomeResponse.apply)
// 처럼 미리 구현된 람다 함수를 transformer 로 넘겨줄 수 있습니다.
// (apply 함수는 스칼라에서 기본으로 제공되는 생성자 메서드입니다. SomeEntity => SomeResponse 의 형태)
이제 컨트롤러에서 transformer 만 갈아끼워주면 서비스는 신경 쓸 필요 없이 반환 값을 변경할 수 있습니다!
(위 코드는 수도 코드라고 생각해 주세요..ㅎㅎ 문법이 중구난방이군요)
여기에 스칼라에서 자주 사용되는 implicit 과 커링, 디폴트 파라미터를 적용하면 아래와 같이 작성할 수도 있습니다.
def search[T](someRequest : SomeRequest)(implicit transformer : SomeEntity => T = identity _) : T = {
val someEntity : SomeEntity = someRepository.find(someRequest)
return transformer(someEntity)
}
search(someRequest = someRequest)
// 이렇게 transformer 를 안 넘겨주는 경우엔 transformer 가 SomeEntity => SomeEntity 로 동작합니다.
// identity 는 A 를 받아 A 를 그대로 넘겨주는 항등함수!
아직 정말 간단히 하나의 메서드에만 적용했지만, 여러 추상화를 통해 더 우아한 transformer 를 만들 수도 있지 않을까 싶네요.ㅎㅎ
binchoo, emiling and wooyounggggg
Metadata
Metadata
Assignees
Labels
No labels