파사드 패턴(Facade Pattern)

  • 파사드 패턴은 복잡하게 분리된 모듈의 결합입니다.
  • 다른 말로는 연관된 서브 시스템의 메서드를 하나로 결합한 형태입니다.
  • API를 사용해본 경험이 있다면, 대부분 파사드 패턴을 보았고, 사용하고 있습니다.
  • 이처럼 파사드 패턴은 사용자에게 제공되는 최상위 통합 인터페이스입니다.

파사드 패턴의 구조

  • 파사드 패턴은 특별한 구조보다는 작성 규칙이 존재합니다.
    • 자기 자신만의 객체 사용
    • 메서드에 전달된 매개변수 사용
    • 메서드에 생성된 객체 사용
    • 객체에 속하는 메서드 사용
  • 먼저, 파사드 패턴을 활용했지만 잘못된 예시를 살펴보겠습니다.

잘못된 파사드 패턴의 예제

  • 불필요한 객체 생성 루틴과 재호출을 코드에 삽입하는 경우가 많습니다.
 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
#pragma once

// 서브시스템
class Thermometer
{
public:
    float getTemperature()
    {
        return m_temperature;
    }

private:
    float m_temperature;
};

// 파사드 패턴(잘못된 사용)
class Temperature
{
public:
    Temperature(Thermometer thermometer)
    {
        m_thermometer = thermometer;
    }

    float getTemp()
    {
        // 새로운 객체 생성
        Thermometer thermometer = getThermometer();

        // 새로운 객체로부터 반환
        return thermometer.getTemperature();

        // to-be
        //return m_thermometer.getTemperature();
    }

private:
    // 불필요한 메서드 호출
    Thermometer getThermometer()
    {
        return m_thermometer;
    }

    Thermometer m_thermometer;
};

파사드 패턴의 규칙을 활용한 예제

  • 파사드 패턴은 다수의 객체를 하나의 인터페이스로 관리하는 패턴입니다.
  • 복잡한 서브 시스템 A, B를 만드는 두 명의 개발자가 있습니다.
    • 이들은 서로의 작업 결과물을 위해 서로의 객체에 의존성을 갖습니다.
    • 이렇게 복잡한 서브 시스템들끼리의 연결은 매우 복잡한 결과를 낳습니다.
    • 복잡한 서브 시스템 A와 B 사이에 파사드 패턴을 활용한 인터페이스를 만든다면…
    • 객체의 연결 복잡성이 낮아지며 사용하기 편한 구조로 변경됩니다.
  • 이와 관련된 간단한 예제를 하나 살펴보겠습니다.

파사드 패턴: 복잡한 서브 시스템

 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
class Package1
{
public:
    Package1()
    {
        std::cout << "concrete Package1 object" << std::endl;
    }

    void process()
    {
        std::cout << "[Package1] do process.." << std::endl;
    }
};

class Package2
{
public:
    Package2()
    {
        std::cout << "concrete Package2 object" << std::endl;
    }

    void process()
    {
        std::cout << "[Package2] do process.." << std::endl;
    }
};

class Package3
{
public:
    Package3()
    {
        std::cout << "concrete Package3 object" << std::endl;
    }

    void process()
    {
        std::cout << "[Package3] do process.." << std::endl;
    }
};

파사드 패턴: 파사드 패턴을 사용한 인터페이스

  • 파사드 패턴의 형태는 매우 다양합니다.
  • 개발된 서브 시스템에 따라 적절히 사용합니다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Facade
{
public:
    Facade()
    {
        m_package1 = std::make_shared<Package1>();
        m_package2 = std::make_shared<Package2>();
        m_package3 = std::make_shared<Package3>();
    }

    // 모든 프로세스를 실행하는 예제
    void processAll()
    {
        m_package1->process();
        m_package2->process();
        m_package3->process();
    }

private:
    std::shared_ptr<Package1> m_package1;
    std::shared_ptr<Package2> m_package2;
    std::shared_ptr<Package3> m_package3;
};