Skip to content

transformer 적용기 #19

@leejaeseung

Description

@leejaeseung

이전에 스터디에서 잠깐 말씀드린 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 를 만들 수도 있지 않을까 싶네요.ㅎㅎ

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions