디자인 패턴 101 - FACADE

subutai·2021년 4월 6일
0

디자인 패턴 101

목록 보기
1/3

디자인 패턴 강의를 수강하면서 개인적으로 정리하고 각 디자인 패턴을 Deep-Dive 해보는 시리즈!
GoF 는 좋은 디자인 패턴서적임이 분명하지만
쓰여진지 워낙 오래되었기 때문에 예시가 와닿지 않는 경우가 많고
사용되는 용어가 실무에서 사용되는 용어와는 거리가 있기에
읽어도 읽히지 않는 기분이 드는데요..
각 용어를 최대한 친숙한 용어와 요즘 시대에 맞는 예제로 바꾸어서 이해해보고자 합니다.

Facade

의도

서브시스템 내의 인터페이스 집합에 대한 획일화된 하나의 인터페이스를 제공하는 패턴으로, 서브시스템을 사용하기 쉽도록 상위 수준의 인터페이스를 정의합니다.

풀어써본 의도

의도에서 제일 모호한 부분은 '서브시스템' 이라는 키워드였습니다.
서브시스템이란 키워드에 대해 조금 생각해보고
조사를 해본 결과 아래와 같이 보다 친숙한 형태로 생각할 수 있었습니다.

시스템은 하나의 포괄적인 프로그램(IDE)
서브시스템은 IDE에서 제공하는 하나의 범주로
묶일 수 있는 기능의 집합이라고 생각할 수 있습니다.

말이 다시 어려워지는데, GoF의 예시로 생각하면
컴파일러는 아시다시피 여러 과정을 거쳐서 컴파일을 수행하는데요.
스캐닝, 파싱, AST트리 생성 등등 과정을 거치기 때문에 각 각의 기능을 위해
클래스로 분해해서 만드는게 자연스럽게 됩니다.
스캐닝을 하는 클래스, 파싱을 하는 클래스, 트리를 생성하는 클래스로요
그래서 가상의 컴파일러 서브시스템을 구성한다면 아래와 같은 클래스로 만들 수 있겠어요

  1. Scanner
  2. Parser
  3. ProgramNode
  4. ByteCodeStream
  5. ProgramNodeBuilder

그런데, IDE에서 컴파일을 실행시켰을 때, 컴파일이 실패된 이유에 대해서 사용자에게
알려주고자 한다면 어떻게 해야할까요?
IDE라는 시스템이 컴파일 하는 책임을 맡은 컴파일러 서브시스템에게 이에대한 정보를 얻어야할 것입니다.

여기서 조금 예제에 대해 이해해주셔야할 부분은
IDE는 독립적으로 존재하는 컴파일러(GCC, Mingw)를 단순히 사용하기 때문에
스캐닝, 파싱 등등의 절차에 대해 전혀 알지 못하지만, 이 예제에서는 설명의 용이성을 위해
IDE 시스템이 컴파일 기능을 포함하고 있는것으로 가정합니다

그러면 위와같이, 컴파일 에러가 발생할 수 있는 컴파일러 서브시스템에 의존해야할거에요
여기서 생길 수 있는 문제가 무엇일까요? 저는 아래와 같이 생각합니다.

  1. IoC 원칙처럼, 상위시스템이 하위시스템의 구현에 의존하게 됩니다
    컴파일러 서브시스템을 구성하는 클래스 집합이 바뀐다면 IDE 시스템의
    컴파일 기능이 영향을 받게 됩니다! 좋지않은 냄새입니다
  2. 사용하는것이 어렵습니다. IDE 시스템이 컴파일러 서브시스템의 구체적인 클래스를 알아야합니다
  3. 병렬적인 개발이 어렵습니다. 컴파일러 서브시스템의 구체적인 명세가 나오기 전까지는
    IDE 시스템에서 컴파일 기능과 연동하기 어렵습니다.

이제 FACADE 를 적용시킨다면 아래처럼 바꾸면서 문제를 해결할 수 있습니다!

디자인패턴 적용


위와같이 바꾼다면, 앞에서 다루지는 않았지만 Compile 하는 기능자체도
Scanner.method() -> parser.method() -> ProgramNode.method() .. -> .. -> 컴파일 끝!
처럼 IDE 시스템에서 일일히 컴파일 서브시스템의 어떤 클래스의 어떤 메소드를 어떤 순서로
실행해야하는지 알 필요 없이, compile() 만 호출하면 되는것이죠

컴파일 에러를 확인하는 예시는 어떨까요?
더 이상 컴파일러 서브시스템에서 어떤 클래스가 에러를 만들어내는지 알 필요 없이
getCompileErr()를 호출해보면 알 수 있겠습니다.

FACADE 패턴 장점

  1. 패턴을 적용하면 확장성을 고려하여 설계하기 때문에, 작은 클래스가 만들어지는데
    서브시스템을 재사용 가능하고 재정의 할 수 있도록 만들어주기는 하지만
    클래스가 워낙 많아지므로 시스템이 커질수록 사용하기가 어려워지는데
    FACADE는 서브시스템에 대해 단순하고 기본적인 인터페이스를 제공하기 때문에
    협업하는 개발자들에게 적합한 클래스의 형태를 제공하게 됩니다.

    여기서 패턴이란 FACADE외에 COMMAND, INTERPRETER, STRATEGEY 등을 의미합니다

  2. FACADE의 사용을 통해 사용자와 다른 서브시스템 간의 결합도를 줄일 수 있습니다
    즉, 서브시스템에서는 자신이 공개하고자 하는 메소드만 지정해서 공개할 수 있기에
    사용자와 서브시스템 사이의 호출 횟수는 실질적으로 감소하게 됩니다.

    FACADE패턴은 서브시스템이 제공하고자 하는 것만 제공할 수 있기 때문에
    다른 서브시스템이 이 서브시스템내의 여러 메소드를 직접 호출할 일이 없어지기에
    디버깅, 성능튜닝 및 의존성 감소의 효과를 얻을 수 있습니다

  3. 서브시스템이 다른 서브시스템에 종속적이라도, FACADE를 통해서만 소통하기 때문에
    서브시스템간의 종속성이 줄어듭니다

    (2)번과 매우 유사한 장점입니다

  4. 사용자가 다뤄야하는 객체의 수가 줄어든다

    FACADE로 묶어놓았기 때문에

  5. 코드의 결합도를 약하게 만듭니다

    여기서 얻게되는 장점이 있는데, 컴파일 의존성이 매우 줄어들게 됩니다.
    다른 서브시스템의 FACDE를 사용하는 서브시스템은 FACADE의 인터페이스만 알기에
    FACADE내에서 작동하는 클래스들이 수정되었을 때, FACADE만 새로 컴파일해줄 뿐
    FACADE를 사용하는 다른 서브시스템의 재컴파일이 필요하지 않습니다

`

0개의 댓글