본문 바로가기
필수 개발지식/디자인패턴

[Design Pattern] 퍼사드 패턴 (Facade)

by 코딩하는짱구 2023. 5. 12.
반응형

[Design Pattern] 퍼사드 패턴 (Facade)

✅구조패턴의 퍼사드(Facade)에 대해 알아보자!

 


퍼사드패턴이란?

결론부터 말하면 복잡하고 다양한 서브시스템을 인터페이스로 감싸 간단하게 만드는 패턴!!

 

 

 

 

 

 

 

 

facade는 "건물의정면"을 의미하는 단어로 어떤 소프트웨어의 다른 커다란 코드 부분에 대하여 간략화된 인터페이스를 제공해주는 디자인 패턴을 의미한다. 

우리는 벽만 보일뿐 벽 안에 안쪽은 어떻게 설계되있는지 모른다.

 

예를 들어, 우리가 쇼핑몰에서 옷을 사기 위해 접하는건 핸드폰화면뿐이다. 

옷을 구매하는 작업이 완료되는데 뒷면에서 이루어지는 수많은 작업들은 우리가 알 필요도 없고, 판매자는 그 과정을 소비자에게 알게해서도 안된다. 

 

아래와 같이 고객이 '옷을 구매'하는 작업을 요청하면 facade가 옷을 구매하기 위해 사용하는 서브 클래스들 사이의 간단한 통합 인터페이스를 제공해주는 역할을 하게 된다. 즉 아래와 같은 형태의 facade를 벽이라고 표현하는 것.

 

 

 

facade의 이해2

 

**즉 퍼사드는 중재자 패턴의 일종이다!

중재자 패턴은 서로 상호작용하는 객체들 간의 복잡한 통신을 중재자 객체를 통해 처리하는 디자인 패턴으로,

중재자는 객체들 사이의 상호작용을 캡슐화하고 조정하는 역할을 한다.

 

 

 

 

 

 

 

 

 

 


퍼사드패턴은 왜 쓰이나요?

  • 복잡한 코드 기반에서 코드간의 의존성을 낮추고, 코드의 유지 보수성을 향상시킨다. 
  • 클라이언트 코드와 서브 시스템간의 결합도를 낮추며, 클라이언트 코드를 단순화 시킬 수 있다. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


퍼사드패턴은 어떻게 쓰이나요?

자바스크립트에서 퍼사드 패턴은 객체 지향 프로그래밍에서 주로 사용된다.

퍼사드 객체는 클라이언트와 서브시스템사이의 중재자 역할을 하며, 클라이언트의 요청을 받아 서브 시스템으로 전달하고 결과를 반환한다. 즉 클라이언트는 단순히 퍼사드 객체의 인터페이스를 호출하여 서브시스템과 상호작용할 수 있다. 

 

 

ex)

우리가 function SubsystemOne, Two, Three라는 클래스의 서브 시스템을 실행시켜서

Subsystem One: Operation One
Subsystem Two: Operation Two
Subsystem Three: Operation Three

라는 결과값을 도출하려고 한다고 가정해보자. 

 

 
//pacade를 쓰지 않았을 경우

// 서브시스템
function SubsystemOne() {
  this.operationOne = function () {
    console.log('Subsystem One: Operation One');
  };
}

function SubsystemTwo() {
  this.operationTwo = function () {
    console.log('Subsystem Two: Operation Two');
  };
}

function SubsystemThree() {
  this.operationThree = function () {
    console.log('Subsystem Three: Operation Three');
  };
}

// 클라이언트
var subsystemOne = new SubsystemOne();
var subsystemTwo = new SubsystemTwo();
var subsystemThree = new SubsystemThree();

// 클라이언트 코드에서 서브시스템에 직접 접근
subsystemOne.operationOne();
subsystemTwo.operationTwo();
subsystemThree.operationThree();

위의 코드에서 명확하게 알 수 있는 단점

  • 클라이언트 코드가 서브시스템에 직접적으로 접근을 하고 있다.
  • 클라이언트 코드는 서브 시스템의 복잡한 구조와 상세한 동작을 알아야만 한다.
  • 그에 따라 더 많은 코드를 작성해야하며, 서브시스템의 변경에 따라 많은 수정이 필요할 수 있다.

 

 

 

이런 문제를 해결하기 위해서 facade를 적용한다면, 

// 서브시스템
function SubsystemOne() {
  this.operationOne = function () {
    console.log('Subsystem One: Operation One');
  };
}

function SubsystemTwo() {
  this.operationTwo = function () {
    console.log('Subsystem Two: Operation Two');
  };
}

function SubsystemThree() {
  this.operationThree = function () {
    console.log('Subsystem Three: Operation Three');
  };
}

// 퍼사드
function Facade() {
  this.subsystemOne = new SubsystemOne();
  this.subsystemTwo = new SubsystemTwo();
  this.subsystemThree = new SubsystemThree();

  this.operation = function () {
    this.subsystemOne.operationOne();
    this.subsystemTwo.operationTwo();
    this.subsystemThree.operationThree();
  };
}

// 클라이언트
var facade = new Facade();
facade.operation();

//Subsystem One: Operation One
//Subsystem Two: Operation Two
//Subsystem Three: Operation Three

위의 코드에선 'Facade' 객체가 클라이언트와 서브시스템 사이의 중재자 역할을 한다. 

따라서 클라이언트는 단순히 Facade의 operation메서드를 호출하여 서브 시스템과 상호작용할 수 있다. 

 

 

이해하기 쉽게 파일을 파일을 가공하는 과정을 퍼사드로 만들어본다면 아래와 같다.

클라이언트가 단순히 파일을 다운로드 받고싶은 상황이라고 가정할때, 우리는 파일을 가공하는 과정인 다운로드, 파일 처리 2가지의 서브시스템을 하나의 퍼사드 operation으로 만들어 줄 수 있다.

 

// 서브시스템
function FileDownloader() {
  this.downloadFile = function (url) {
    console.log('Downloading file from:', url);
    // 파일 다운로드 로직
  };
}

function FileProcessor() {
  this.processFile = function (file) {
    console.log('Processing file:', file);
    // 파일 처리 로직
  };
}

// 퍼사드
function FileDownloaderFacade() {
  this.downloader = new FileDownloader();
  this.processor = new FileProcessor();

  this.downloadAndProcessFile = function (url) {
    this.downloader.downloadFile(url);
    this.processor.processFile(url);
  };
}

// 클라이언트
var fileDownloaderFacade = new FileDownloaderFacade();
fileDownloaderFacade.downloadAndProcessFile('https://example.com/file.txt');

//Downloading file from: https://example.com/file.txt
//Processing file: https://example.com/file.txt

 

 

위의 예시들을 종합해본다면 결국 퍼사드는,

 

 

 

 

 

 

 

 

 

 

 

 

 


✅퍼사드(Facade)의 단점은 뭔가요?!

  • 제한된 유연성: 퍼사드 객체는 클라이언트와 서브시스템 사이의 중간자 역할을 수행하기 때문에, 서브 시스템의 내부 구조를 숨기고 간단한 인터페이스만 제공한다. 이로인해 클라이언트가 서브시스템의 세부기능에 직접 접근하는 것이 어렵다. 
  • 복잡성 증가: 퍼사드 패턴을 사용하면 코드에 추가적인 추상화 계층이 도입된다. 이로 인해 코드의 이해와 디버깅이 어려워질 수 있다. 
  • 클라이언트의 퍼사드 객체에 대한 의존성 증가: 퍼사드 객체가(내부동작, 즉 서브시스템들이) 변경되면 클라이언트 코드도 함께 수정해야한다, 이로인해 퍼사드 객체의 변경이 전체 시스템에 영향을 미칠 수 있다. 

 

 

 

**질문사항에 대한 답변

Q. 자바스크립트에서 컨트롤러와 퍼사드는 같은건가요? 

A. 컨트롤러와 퍼사드는 둘 다 디자인 패턴의 일종이지만 같은 것은 아닙니다. 

 

Facade vs Front Controller

퍼사드는 내부 시스템의 복잡도를 감추기 위해 복잡한 기능을 감싸고 상호작용할 더 단순한 메소드를 제공하는 계층이라고 생각할 수 있다. 퍼사드는 클라이언트가 원하는 바를 듣고 내부 시스템을 적절히 이용하여 요청을 이루어주는(어떻게 보면 번역과 같은 일) 이외의 로직을 담고 있어선 안된다.

 

반면에 컨트롤러는 컨트롤러 자체가 자신만의 로직을 가질 수 있다. 또한 프론트 컨트롤러의 목적은 내부 시스템의 복잡도를 감추기 위함이라기보다 모든 요청을 먼저 받는 컨트롤러를 하나 둠으로써 모든 요청에 공통적으로 처리해야하는 로직을 효과적으로 적용하는데 있다.

 

 

 

 

참고문헌: https://live-everyday.tistory.com/210, https://refactoring.guru/ko/design-patterns, https://aljjabaegi.tistory.com/627

반응형