Programming/C++

C++ 퍼사드 패턴

_SYPark 2021. 5. 16. 18:05
728x90

우리가 설계를 하다 보면 너무 많은 클래스들을 사용한다면 한눈에 결과나 구조를 파악하기가 쉽지 않습니다. 이럴 때 서브 시스템을 통해 밀접하게 관련된 객체나 클래스들을 묶어 추상화하여 정의하는 방법이 있습니다. 서브시스템을 이용한다면 복잡한 내용도 얼추 파악하는 것이 가능해집니다. 서브시스템을 정의할 때 명확한 구분이 존재하지 않아 특정 클래스를 포함시키고 말고 그리고 그에 관한 관계 구성도 명확하지 않습니다. 그렇다고 하나의 서브시스템에 모든 클래스를 포함시키는 것은 서브시스템의 의미도 애매해지게 됩니다. 이러한 문제들을 해결하면서 복잡한 설계 내용을 서브시스템 단위로 간략히 정의할 수 있는 방법을 소개합니다.

 

우리가 검색을 하면 프로그램은 조건에 맞는지 확인하고 데이터베이스에 접속하고 검색에 맞는 SQL문을 생성하고 관리 시스템에 전달하여 결과를 받아오고 그 결과를 화면에 보여주는 과정까지의 구조를 가지고 있습니다. 각 과정에 대한 클래스들이 존재하는데 사용자가 클래스들 모두를 활용해서 사용하는 구조를 가지게 되면 아래와 같은 구조가 됩니다.

위와 같은 구조가 되면 사용자가 모든 과정에 대한 객체를 생성해줘야 하기 때문에 모든 과정을 알고 있어야 합니다. 이거보다 더 복잡한 과정을 거치게 될수록 사용자가 사용하기 너무 불편한 환경입니다. 쉽게 사용하기 위해서는 이런 과정을 총괄하는 핸들러 클래스를 만들어서 사용하게 하는것이 좋습니다. 이제 이 핸들러 클래스 안에서 사용되는 클래스들로 서브시스템을 정의한 것입니다. 서브시스템 안에서는 여러 클래스들이 밀접한 관계를 가지고 있고 사용자는 각각의 클래스에 접근하지 않아도 대표 클래스를 통해 접근하는 구조를 퍼사드 패턴이라고 합니다. 그리고 이런 대표 클래스를 퍼사드 클래스라고 합니다. 

class SearchCond { bool check() { } }; // check Logic
class Database { bool execute(string sql, ListDBResult& result) { } };  // 전달된 sql 실행
class Generator { string generateSQL(SearchCond cond) { } };	// sql 문장 생성

class DBHandler {
    bool Search(map<string, string> nvList, ListDBResult& result) {
        SearchCond cond(nvList);
        if ( !cond.check()) { cout << "Wrong Cond Data"; }
        SQLGenerator generator;
        string sql = generator.GenerateSQL(cond);
        
        return db.Execute(sql, result);
    }
private:
    Database db;
};

int main()
{
    map<string, string> nvList;
    ListDBResult result;
    
    DHHander handler;
    handler.Search(nvList, result);
}

퍼사드를 통해 서브시스템을 구현하여 사용하면 퍼사드 클래스의 인터페이스를 통한다면 복잡한 과정을 사용자가 알 필요가 없어집니다. 서브시스템 내부가 바뀌어도 사용자는 같은 인터페이스를 통해 접근하기 때문에 변경 내용을 알 필요가 없습니다.

퍼사드 패턴은 결국 객체지향의 정보 은닉과도 일맥상통하는 부분이 됩니다. 사용자가 서브시스템에 접근 권한을 제한할 때 public, private와 같은 접근지정자로 제한할 수도 있지만 namespace를 통해서도 해결해줄 수 있습니다. 서브시스템 별로 namespace를 지정해주면 서브시스템 내의 클래스가 의도하지 않게 참조되는 것을 방지할 수 있습니다.

728x90