Web/JS

[JS] 디자인 패턴(Design Pattern)_퍼사드 패턴(Facade Pattern)

메바동 2023. 3. 1. 01:27
728x90

"JavaScript Design Pattern" 포스팅은 ChatGPT에게 "Essential design patterns for JavaScript developers to learn"로 질문한 뒤 나온 내용에 대해 정리하는 포스팅입니다.

 


 

1. 퍼사드 패턴(Facade Pattern)

퍼사드 패턴은 클래스, 인터페이스 및 하위 시스템으로 구성된 복잡한 시스템에 단순화된 인터페이스를 제공하는 구조 디자인 패턴이다.

클라이언트는 단일 인터페이스를 통해 시스템과 상호 작용할 수 있으며, 시스템 내 개별 구성 요소의 복잡성과 상호 작용을 숨길 수 있다.

 

JavaScript에서 퍼사드 패턴은 일반적으로 복잡한 API, 라이브러리 또는 프레임워크와의 상호작용을 단순화하는 데 사용된다.

이 패턴은 컴포넌트 간의 결합을 줄이고 코드베이스를 보다 모듈화 및 유지 관리하기 쉽게 만드는 데 도움이 될 수 있다.

 

퍼사드 패턴에는 일반적으로 다음 요소가 포함된다.

 

  1. 퍼사드: 클라이언트가 상호 작용하는 인터페이스이다. 적절한 하위 시스템에 요청을 위임하여 시스템에 간소화된 인터페이스를 제공한다.
  2. 하위 시스템: 시스템을 구성하는 구성 요소들이다. 특정 작업을 수행하고 시스템 기능의 특정 부분을 담당한다. 하위 시스템은 복잡할 수 있으며, 많은 개별 구성 요소와 인터페이스로 구성된다.
  3. 클라이언트: 퍼사드와 상호작용하는 코드이다. 일반적으로 시스템을 사용해야 하며, 그렇지 않으면 하위 시스템과 직접 상호 작용해야 하는 코드이다. 

 

다음은 JavaScript로 구현한 퍼사드 패턴의 예이다:

 

class SubsystemA {
  operationA() {
    console.log('Subsystem A operation');
  }
}

class SubsystemB {
  operationB() {
    console.log('Subsystem B operation');
  }
}

class SubsystemC {
  operationC() {
    console.log('Subsystem C operation');
  }
}

class Facade {
  constructor() {
    this.subsystemA = new SubsystemA();
    this.subsystemB = new SubsystemB();
    this.subsystemC = new SubsystemC();
  }

  operation1() {
    console.log('Operation 1');
    this.subsystemA.operationA();
    this.subsystemB.operationB();
  }

  operation2() {
    console.log('Operation 2');
    this.subsystemB.operationB();
    this.subsystemC.operationC();
  }
}

// Usage
const facade = new Facade();
facade.operation1();
facade.operation2();

 

이 예제에서 Facade는 SubsystemA, B, C에 대한 단순화된 인터페이스를 제공한다.

Facade 클래스는 생성자에서 이러한 하위 시스템을 초기화하고 두 가지 메서드, 즉 operation1()과 operation2()를 제공한다.

이러한 메서드는 요청을 적절한 서브시스템에 위임하여 클라이언트에서 개별 서브시스템의 복잡성을 숨긴다.

 

퍼사드 패턴을 사용하면 클라이언트는 단일 인터페이스를 통해 시스템과 상호 작용할 수 있으며, 개별 하위 시스템의 세부 사항에 신경 쓸 필요가 없다.

따라서 코드베이스가 더 모듈화 되고 유지보수가 쉬워진다.

 

 

 

2. Facade Pattern 연습 코드

ChatGPT에게 "Give me a challenge to practice the Facade Pattern in JavaScript."라고 질문한 뒤 나온 문제와 그에 대한 답이다.

 

 

스켈레톤 코드는 다음과 같다.

 

// Step 1: Define the StockMarketAPI class
class StockMarketAPI {
  // TODO: Implement the methods for getting stock prices and buying/selling stocks
}

// Step 2: Implement the StockMarketFacade class
class StockMarketFacade {
  constructor(api) {
    // TODO: Implement the constructor
  }

  getStockPrice(stockSymbol) {
    // TODO: Implement the getStockPrice method
  }

  buyStock(stockSymbol, amount) {
    // TODO: Implement the buyStock method
  }

  sellStock(stockSymbol, amount) {
    // TODO: Implement the sellStock method
  }
}

// Step 3: Usage
const api = new StockMarketAPI();
const facade = new StockMarketFacade(api);
console.log(facade.getStockPrice('AAPL')); // should output the price of AAPL stock
console.log(facade.buyStock('AAPL', 100)); // should output true if the purchase was successful
console.log(facade.sellStock('AAPL', 50)); // should output true if the sale was successful

 

이를 구현한 코드는 다음과 같다. 

 

// Step 1: Define the StockMarketAPI class
class StockMarketAPI {
  // TODO: Implement the methods for getting stock prices and buying/selling stocks
  private stock = new Map<string, number>();

  getPrice(stockSymbol: string): number {
    if (!this.stock.has(stockSymbol)) {
      const price = Math.random() * 100;
      this.stock.set(stockSymbol, price);  
    }

    return this.stock.get(stockSymbol)!;
  }

  buy(stockSymbol: string, amount: number): boolean {
    return this.getPrice(stockSymbol) <= amount;
  }

  sell(stockSymbol: string, amount: number): boolean {
    const price = this.getPrice(stockSymbol);
    return price * 1.3 >= amount && price * 0.7 <= amount;
  }
}

// Step 2: Implement the StockMarketFacade class
class StockMarketFacade {
  private api: StockMarketAPI;

  constructor(api: StockMarketAPI) {
    // TODO: Implement the constructor
    this.api = api;
  }

  getStockPrice(stockSymbol: string) {
    // TODO: Implement the getStockPrice method
    return this.api.getPrice(stockSymbol);
  }

  buyStock(stockSymbol: string, amount: number) {
    // TODO: Implement the buyStock method
    return this.api.buy(stockSymbol, amount);
  }

  sellStock(stockSymbol: string, amount: number) {
    // TODO: Implement the sellStock method
    return this.api.sell(stockSymbol, amount);
  }
}

// Step 3: Usage
const api = new StockMarketAPI();
const facade = new StockMarketFacade(api);
console.log(facade.getStockPrice('AAPL')); // should output the price of AAPL stock
console.log(facade.buyStock('AAPL', 100)); // should output true if the purchase was successful
console.log(facade.sellStock('AAPL', 50)); // should output true if the sale was successful
728x90