[Structural Pattern] 퍼사드 패턴 (Facade Pattern)
Design Pattern / Structural Pattern
퍼사드 패턴의 정의와 해당 디자인 패턴의 예제 코드를 통한 이해 및 설명 정리
개념
- 사용하기 복잡한 클래스 라이브러리에 대해 사용하기 편하게 간편한 인터페이스( - API)를 구성하기 위한 구조 패턴- 예를 들면, 교제를 보고 필기노트에 재정리를 하듯이 클래스를 재정리하는 행위로 보면 됨
 
- 프로그램이 업데이트를 하면서 버전이 올라갈수록 많은 클래스들이 만들어져 점점 복잡해지는 상황에 놓이게 되는데, 이러한 거대한 솔루션을 구성하려면 상호 관련된 많은 클래스들을 적절히 제어해야 할 필요성이 있으며, 이때 이 처리를 개별적으로 제어하는 것이 아닌 일종의 ‘창구’를 준비하여 중계할 수 있도록 구성하는 과정 - 고객은 복잡한 절차 지식없이 고객센터(창구)에 요구만 하면 결과를 얻음 
- 정리하면, 퍼사드 패턴은 복잡하게 얽혀있는 것을 정리해서 사용하기 편한 인터페이스를 고객에게 제공한다고 보면 되며, 고객은 복잡한 시스템을 알 필요없이 시스템의 외부에 대해서 단순한 인터페이스를 이용하기만 하면 됨 
패턴 구조
- Facade- SubSystem기능을 편리하게 사용할 수 있도록 하기 위해 여러 시스템과 상호 작용하는 복잡한 로직을 재정리해서 높은 레벨의 인터페이스를 구성
- Facade역할은- SubSystem의 많은 역할에 대해 ‘단순한 창구’가 됨
- Client와- SubSystem이 서로 긴밀하게 연결되지 않도록 함
- 반드시 한 개만 존재해야 한다는 규칙은 없으며, 연관되지 않은 기능이 있다면 얼마든지 - Facade를 별도로 분리해서 사용할 수 있음- 다른 Facade에서 사용할 수도 있으며,Client에서 직접 접근도 가능
 
- 다른 
 
- SubSystem- 수십 가지의 라이브러리 혹은 클래스들
 
- Client- SubSystem에 직접 접근하는 대신- Facade를 사용
 
예제 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// DBMS에 저장된 데이터를 나타내는 클래스
class Row {
  private name: string;
  private birthday: string;
  private email: string;
  constructor(name: string, birthday: string, email: string) {
    this.name = name;
    this.birthday = birthday;
    this.email = email;
  }
  public getName(): string {
    return this.name;
  }
  public getBirthday(): string {
    return this.birthday;
  }
  public getEmail(): string {
    return this.email;
  }
}
class DBMS {
  private db = new Map<string, Row>();
  public put(name: string, row: Row): void {
    this.db.set(name, row);
    // Java 코드에서는 put
  }
  // DB에 쿼리를 날려 결과를 받아오는 메소드
  public query(name: string) {
    try {
      setTimeout(() => {}, 1000);
    } catch (e) {}
    return this.db.get(name.toLowerCase());
  }
}
class Caches {
  private caches = new Map<string, Row>();
  public put(row: Row): void {
    this.caches.set(row.getName(), row);
  }
  public get(name: string) {
    return this.caches.get(name);
  }
}
class Message {
  private row: Row;
  constructor(row: Row) {
    this.row = row;
  }
  public makeName(): string {
    return 'Name : "' + this.row.getName() + '"';
  }
  public makeBirthday(): string {
    return "Birthday : " + this.row.getBirthday();
  }
  public makeEmail(): string {
    return "Email : " + this.row.getEmail();
  }
}
export { Caches, DBMS, Message, Row };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { Caches, DBMS, Message, Row } from "./libraries";
export class Facade {
  private dbms: DBMS = new DBMS();
  private caches: Caches = new Caches();
  /**
   * 1. 생성 & 등록
   */
  public insert(): void {
    this.dbms.put(
      "한형진",
      new Row("한형진", "1996-12-10", "han1210_36@naver.com")
    );
    this.dbms.put(
      "홍길동",
      new Row("홍길동", "1890-08-14", "honggildong@naver.com")
    );
    this.dbms.put(
      "임꺽정",
      new Row("임꺽정", "1820-11-02", "han1210_36@naver.com")
    );
  }
  /**
   * 1. 캐시에 row가 없다면 DB에 해당 데이터를 조회하고 row에 저장 후, 캐시에 저장
   * 2. DB에 이름으로 조회된 값이 있으면 정상적으로 값 출력
   * 3. 캐시, DB에 조회된 값이 없다면 에러 문구 출력
   */
  public run(name: string): void {
    let row = this.caches.get(name);
    if (!row) {
      row = this.dbms.query(name);
      if (row) {
        this.caches.put(row);
      }
    }
    if (row) {
      const message: Message = new Message(row);
      console.log(message.makeName());
      console.log(message.makeBirthday());
      console.log(message.makeEmail());
    } else {
      console.log(name + "의 데이터가 DB에 존재하지 않습니다.");
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { Facade } from "./facade";
class Client {
  public main(name: string, _args?: string[]): void {
    const facade: Facade = new Facade();
    facade.insert();
    facade.run(name);
  }
}
const client_hhj = new Client();
const name_hhj = "한형진";
client_hhj.main(name_hhj);
console.log("");
// Name : "한형진"
// Birthday : 1996-12-10
// Email : han1210_36@naver.com
const client_hgd = new Client();
const name_hgd = "홍길동";
client_hgd.main(name_hgd);
console.log("");
// Name : "홍길동"
// Birthday : 1890-08-14
// Email : honggildong@naver.com
const client_nobody = new Client();
const name_nobody = "누군가";
client_nobody.main(name_nobody);
console.log("");
// 누군가의 데이터가 DB에 존재하지 않습니다.
참고한 출처 사이트
 이 기사는 저작권자의  CC BY 4.0  라이센스를 따릅니다.


