본문 바로가기

CS/디자인패턴

[디자인패턴] Facade 패턴

퍼사드 패턴을 설명하는 그림

설명

  복잡한 시스템 구성을 쉽게 사용할 수 있도록 획일화 된 하나의 상위 레벨의 인터페이스를 제공한다.

 하나의 시스템에는 다양한 구성요소가 존재한다. 이때 시스템이 확장되고 보다 구체적으로 설계됨에 따라 이를 구성하는 각 요소들의 복잡도가 높아진다. 현재 시스템을 잘 알고 있다면 이러한 복잡한 아키텍처를 이해하면서 구성요소를 조합하여 새로운 프로그램을 만들 수 있겠지만, 단순히 현재 라이브러리를 사용하고 싶은 개발자 입장에서는 점점 복잡해지는 아키텍처를 전부 이해하며 개발하기가 어렵다. 또한 각 모듈이 제공하는 기능 전부를 사용하는 경우도 드물다.

 따라서 사용자가 시스템의 구성요소 각각을 직접 접근하는 대신, 구성요소를 이용하여 사용자가 원하는 기능을 수행하는 Facade 클래스를 두고, 해당 클래스가 제공하는 인터페이스를 통해 각 기능에 접근하도록 구현한다. 이 경우 사용자는 구성요소들의 역할, 사용법 및 설계를 모르더라도 상위 레벨의 인터페이스를 통해 기능을 사용할 수 있게 된다. 쉽게 말하면 복잡한 모듈들을 하나의 클래스로 감싸고, 클래스가 제공하는 인터페이스만 사용하겠다는 의미다. 일종의 캡슐화를 통해 사용자로부터 구체적 구현 사항과 구성요소를 숨기며, 단순한 사용법만 제공한다. 이 과정에서 정의된 기능을 구현하는데 사용되지 않는 기능들은 그냥 무시된다.

 퍼사드 패턴을 사용하는 경우 사용자가 구체적인 설계나 구체적 동작 방식을 이해해야 하는 부담이 적어진다. 사용자 프로그램과 각각의 서브시스템 사이의 결합도가 낮아지며, 퍼사드 내부의 구체적 구현사항이 변경되더라도 외부에서는 변하지 않는 인터페이스를 통해 기능에 접근할 수 있어 구현 과정이 자유로워지는 특징이 있다.

 장점은 다음과 같다.

  • 구성요소를 숨기고 상위 인터페이스를 통해 기능을 제공하여 사용자가 쉽게 사용할 수 있게 만든다.
  • 서브시스템과 사용자 코드 사이의 결합도를 낮춘다. 퍼사드 패턴에 포함되는 각 구성요소 사이의 결합도는 높아지지만, 사용자 코드에서는 상위 레벨의 인터페이스를 통해 기능에 접근하므로 결합이 감소한다. 낮은 결합도 덕분에 퍼사드로 래핑된 각 모듈들은 다른 모듈에 영향을 주지 않고 컴파일할 수 있어 시간이 절약되며, 이식도 간단해진다.
  • 퍼사드 패턴은 기존의 복잡한 방식의 사용 방법을 완전히 막지는 않으므로(원하면 기존 방식으로 사용도 가능) 퍼사드와 기존 방식 중 어떤 것을 사용할지 사용자가 선택할 수 있다.

구현 고려사항은 다음과 같다.

  •  퍼사드를 추상 클래스로 정의하면 서브클래스를 통해 다른 구현을 구성할 수 있다. 사용자 입장에서는 어차피 추상 클래스를 통해 서브시스템에 접근하므로, 정확히 어떤 서브시스템인지 알 필요가 없다. 특정 환경에 의존적인 코드를 기반으로 서브 시스템이 작성되더라도 해당 시스템에 대한 진입점은 추상적인 퍼사드이므로 구체적인 환경과 관련된 정보를 알 필요 없이 인터페이스만 사용하기 때문이다.
  • 퍼사드 객체는 내부에서 사용하는 클래스를 캡슐화한다. 따라서 일반적인 클래스의 캡슐화 방식과 마찬가지로 무엇을 공개할지, 공개하지 않을지에 대해 정의해야 한다.

구성 요소

  • 퍼사드: 단순하고 일관된 통합 인터페이스를 제공한다. 퍼사드는 사용자의 요청을 각 서브시스템 객체에 전달한다.
  • 서브시스템 클래스들: 자신의 기능을 구현하고 있는 클래스들이다. 클래스들 자체는 자신들을 감싸고 있는 퍼사드에 대한 정보를 가지고 있지 않으며, 단순히 퍼사드 객체가 사용자로부터 전달한 요청을 수행하고, 결과를 알려준다.

예시

 openGL은 그래픽 API이다. 다양한 튜토리얼에서 openGL 그래픽 정보를 윈도우에 띄우는 과정을 가지고 있으나, 사실 윈도우 자체는 openGL에 포함되지 않는다. openGL의 그래픽 정보를 이용하기 위해서는 현재 사용되고 있는 컴퓨터 환경에 맞는 윈도우를 생성하고 여러 정보 및 포맷을 맞춰서 해당 윈도우와 openGL의 컨텍스트를 연결해야 한다.

https://gamedev.stackexchange.com/questions/129660/how-to-initialize-opengl-without-3rd-party-libraries

 절대 대다수의 openGL 튜토리얼 입문자들은 위와 같은 코드를 직접 작성하고 싶어하지 않으며, 실제로도 glfw와 같은 라이브러리를 이용하여 언급한 복잡한 과정을 처리한다. 퍼사드 패턴 측면에서 보면 glfw와 같은 라이브러리들은 윈도우 생성 및 openGL Context를 연결하는데 필요한 다양한 모듈을 사용자에게 숨기고, 대신 "비교적" 간단한 초기화 방법에 대한 인터페이스를 제공한다. 


 퍼사드 패턴은 눈에 띄는 코드 베이스가 존재하지 않는다. 서브 클래스 객체를 얼마나 잘 캡슐화하는지가 관건이라고 할 수 있으며, 이 "얼마나"라는 수치는 정말 케이스 바이 케이스이므로 이런 개념이 있다고 아는데 의미가 있다.

  • 플랫폼에 종속적인 클래스를 감추는데 추상 팩토리 패턴이 사용될 수 있다.
  •  클래스의 기능을 추상화한다는 부분은 중재자 패턴과 비슷하나, 중재자 패턴은 객체 사이의 직접적인 상호작용을 줄이고 협력 관계를 추상화하여 기능의 집중을 막는데 중점을 둔다. 이를 통해 각 클래스의 독립성이 높아지므로 재사용성 및 확장성이 높아지며, 새로운 모듈이 추가되어도 중재자를 통해 연결할 수 있으므로 확장이 가능하다.
     반면 퍼사드 패턴은 인터페이스를 추상화하여 쉽게 사용하는 것이 목적으로, 패턴 내에서 사용되는 객체들 사이는 결합도가 낮지 않다. 애초에 해당 객체들이 제공하는 기능 내에서 사용자가 요구하는 기능만을 인터페이스 형태로 분리하기 때문에 새로운 기능의 추가는 상당히 제한된다.

'CS > 디자인패턴' 카테고리의 다른 글

[디자인패턴] Proxy 패턴  (0) 2023.05.02
[디자인패턴] Mediator 패턴  (0) 2023.04.30
[디자인패턴] SOLID 원칙  (0) 2023.04.27
[디자인패턴] Bridge 패턴  (0) 2023.04.25
[디자인패턴] Singleton 패턴  (0) 2023.04.20