-
프로그래밍 디자인 패턴인 파사드 패턴은 구조 패턴에 속해있습니다. 구조 패턴이란 클래스나 객체를 조합하여 더 큰 구조를 만드는 패턴을 이야기 합니다. 서로 다른 인터페이스를 가진 2개의 객체를 묶어 단일 인터페이스를 제공, 또는 객체들을 서로 묶어 새로운 기능을 제공 할 수 있습니다.
구조 패턴에는 어댑터, 브릿지, 컴포지트, 데코레이터, 플라이웨이트, 프록시 등의 패턴이 있는데 파사드는 어댑터 패턴과 유사하지만 다른 목적을 가지고 있습니다. 어댑터 패턴은 사용자가 사용하고자 하는 다른 인터페이스로 현재의 클래스를 변환하여 제공해주며 어탭터는 인터페이스의 결합 문제등으로 인해 같은 메소드나 클래스에서 사용할수 없는 경우 어탭터를 통해 클래스를 연결하여 사용할수 있다는 특징이 있습니다.
파사드 패턴
파사드 패턴의 특징은 다양한 서비스 로직을 가지는 클래스를 하나의 파사드로 추상화 할수 있다는 점입니다. 사용자는 서비스 클래스의 존재나 구조를 알필요 없이 파사드 클래스만 알고 있으면 됩니다. 파사드는 하위 서비스를 추상화 한다는 점에서 하위 서비스와의 의존성이 낮다고 볼 수 있습니다.
쉽게 표현 해보자면, 자동차를 예를 들 수 있습니다. 우리가 핸들과 브레이크 페달, 액셀이라는 인터페이스를 가지고 자동차의 조향모터, 차체, 엔진, 브레이크등을 컨트롤 하지만 자동차의 모터나 차체, 엔진 브레이크등의 구조나 형태는 알 필요가 없이 내가 가진 인터페이스만 가지고 내가 원하는 기능을 동작시킬 수 있는것 처럼 이러한 복잡한 여러가지 시스템(서비스) 를 인터페이스로 추상화 하여 쉽게 제공해 주는것이 바로 파사드 입니다.
파사드 서비스
public class UserService { public void hello(String name) { System.out.println("Hi ! " + name); } } public class SignService { public void save(String name) { ... } } ... public class FacadeService { private final UserService userService; private final SignService signService; public FacadeService() { userService = new UserService(); signService = new SignService(); } public void registry(String name) { userService.hello(name); signService.save(name); } }
사용자 클래스
public class Client { public static void main(String[] args) { FacadeService facadeService = new FacadeService(); facadeService.bootstrap("mason"); } }
위 코드에서는 UserService 와 SignService 를 결합하여 FacadeService 를 생성했습니다. 사용자는 FacadeService를 가진 인스턴스를 하나 생성하여 유저 서비스와 인증 서비스를 모르고도 해당 기능을 사용할 수 있습니다. 언뜻 보면 클래스를 캡슐화 하는것처럼 보이지만 사실상 캡슐화라고 볼수는 없습니다. 다만 기능을 편하게 사용하고자 인터페이스를 제공 했을 뿐입니다.
스프링에서의 파사드
프로젝트가 커지면서 여러가지 서비스도 많아지고 점점 복잡도가 높아지게 되는데, 대표적으로 서비스 레이어에서 가지는 레파지토리에 대한 너무 많은 의존성이 대표적입니다. 의존성이 높다는건 유지보수가 어렵고 응집도가 낮아진다는 문제점이 생길수 있습니다. 서비스 레이어에서 파사드 패턴은 이런 문제를 어느정도 해결할 수 있습니다.
기존에 하나의 서비스에서 여러 레파지토리를 의존했다면 서비스를 분리하여 하나의 서비스에서 하나의 레파지토리에 의존하게 만들수 있습니다. 여러개로 분리된 서비스는 적절한 파사드 클래스를 통해 의존성을 낮추고 문제점이 발생할 경우 어떤 부분에서 오류가 나는지 명확해 지므로 테스트도 용이해질수 있다고 볼 수 있습니다.
라라벨에서의 파사드
라라벨에서는 대표적으로 서비스 프로바이더를 통해 내가 원하는 시점에 내가 원하는 기능을 로딩하여 사용할 수 있는데. 라라벨에서 제공하는 대부분의 기본 서비스는 파사드 패턴을 통해 구현되어있고 서비스 프로바이더에서 파사드를 생성하여 사용자에게 노출한다. 사실 이런 성격으로 보아 다른 프레임워크의 파사드 보다는 프록시 패턴에 가까운것 같습니다.
DB 라는 파사드가 있는데 서비스 컨테이너에서 제공하는 ORM 이 포함되어있습니다. 자세히 살펴보면 데이터베이스 관련 서비스는 Connect, Builder, Parser 등으로 나누어져 있는데 세가지 서비스를 DB 파사드를 통해 접근할 수 있습니다. 또한 서비스 프로바이더에 대한 정적 프록시를 제공하기 떄문에 서비스 프로바이더를 사용할 경우 객체를 생성하지 않고 정적 객체로 사용할 수 있습니다.
사실 이렇게 설명을 하고 있지만 사실 해당 서비스 프로바이더에서 확인 해보면 서비스 컨테이너에서 DB 서비스 프로바이더를 생성하고 의존성을 주입한뒤 객체를 반환해주는 과정이 있습니다. 정적 메소드라고 볼수 없습니다.
다만 라라벨은 서비스 프로바이더와 파사드 클래스를 적절하게 사용할수 있도록 제공하며 실제로 사용해보면 굉장히 편하게 서비스 컨테이너의 기능을 사용할 수 있습니다.
'Tech' 카테고리의 다른 글
자바스크립트로 배우는 SICP - 함수를 이용한 추상화(2) (0) 2023.05.25 자바스크립트로 배우는 SICP - 함수를 이용한 추상화(1) (0) 2023.05.24 자바스크립트로 배우는 SICP - 들어가며 (0) 2023.05.23 RCA, XLR, TS, TLS? 라인에 대해서 알아보자 (0) 2023.05.18 디자인 패턴, 싱글톤(Singleton pattern) (0) 2023.05.18 댓글