서비스 개발을 하다보면 종종 Facade 이라는 용어를 접할 때가 있다.
서비스 개발할때 말하는 Facade 는 Gof의 디자인 패턴 중 하나인 Facade 패턴으로 보통 패턴은 빼고 Facade라고만 부른다.
여기서는 파사드라고 하겠다.
결론부터 말하면 나는 클래스 이름에 파사드를 포함하는 것을 싫어한다.
파사드란?
여러 하위 시스템 묶어서 편하게 사용하게 해주는 패턴이다.
클라이언트 입장에서는 파사드 하나만 알고 있다면 여러 시스템을 사용할 수 있다.
@Service
class SomeFacade (
private val someService1: SomeService1,
private val someService2: SomeService2,
private val someService3: SomeService3,
) {
@Transactional
fun nice1() {
someService1.nice()
}
@Transactional
fun nice2() {
someService2.nice()
}
@Transactional
fun nice3() {
someService3.nice()
}
}
@RestController
class SomeController(
private val someFacade: SomeFacade,
) {
//...
}
예시처럼 클라이언트인 SomeController
는 SomeFacade
만 알면 SomeService1
,SomeService2
, SomeService3
의 서비스를 사용할 수 있다.
Why 파사드?
내가 생각한 파사드의 사용 이유다.
서비스에서는 dto를 파라미터로 받고 리턴해야한다. → 도메인 모델을 받거나 반환하는 서비스가 필요하다. →
서비스에서 서비스를 주입받는게 불편하다. → 컨트롤러에서 서비스 여러개를 주입받는게 불편하다. →
새로운 계층의 필요하다. → 파사드라는 디자인 패턴이 있다. → 도입하자.
왜 싫은데?
springframework Service 애노테이션 설명이다.
우리는 @Service
로 이미 파사드를 나타낸다.
관례로 postfix Service
를 사용해서 표현한다.
파사드 패턴은 이미 사용중이다.
파사드를 클래스 이름에 포함시킬 필요는 없다.
보통 4계층 구조로 개발할 것이라고 생각한다.
interfaces/api/controller/presentation
application/service
domain
infra/infrastructure
서비스에서 dto를 파라미터로 받고 반환해야 한다는 의견에 동의한다.
그 서비스는 애플리케이션 서비스로 application 계층에 위치한다.
도메인 모델을 받거나 반환하는 서비스가 필요하다 또한 동의한다.
그 서비스는 도메인 서비스로 domain 계층에 위치한다.
우리가 불편해야 하는 것은 서비스에서 서비스를 주입받는 것이 아닌 계층이 오염되는 것에 불편해야 한다.
그래도 서비스에서 서비스로 주입받는게 불편하다면 도메인 서비스의 이름을 다시 생각해보면 좋겠다.
XXXCreationService
→ XXXCreator 또는 (XXXFactory)
XXXValidationService
→ XXXValidator
이름을 바꾸면 한결 domain 계층에 적합하게 느껴진다.
그래도 파사드가 필요하게 느껴진다면, 클래스 분리가 필요하거나 리팩터링이 필요한 시점일 수 있다.
결론
클래스명에 파사드를 포함하는 것을 지양하자.
파사드가 필요하다면 정말 필요한 것인지 생각해보자.