디자인 패턴 강의를 수강하면서 개인적으로 정리하고 각 디자인 패턴을 Deep-Dive 해보는 시리즈!
GoF 는 좋은 디자인 패턴서적임이 분명하지만
쓰여진지 워낙 오래되었기 때문에 예시가 와닿지 않는 경우가 많고
사용되는 용어가 실무에서 사용되는 용어와는 거리가 있기에
읽어도 읽히지 않는 기분이 드는데요..
각 용어를 최대한 친숙한 용어와 요즘 시대에 맞는 예제로 바꾸어서 이해해보고자 합니다.
서브시스템 내의 인터페이스 집합에 대한 획일화된 하나의 인터페이스를 제공하는 패턴으로, 서브시스템을 사용하기 쉽도록 상위 수준의 인터페이스를 정의합니다.
의도에서 제일 모호한 부분은 '서브시스템' 이라는 키워드였습니다.
서브시스템이란 키워드에 대해 조금 생각해보고
조사를 해본 결과 아래와 같이 보다 친숙한 형태로 생각할 수 있었습니다.
시스템은 하나의 포괄적인 프로그램(IDE)
서브시스템은 IDE에서 제공하는 하나의 범주로
묶일 수 있는 기능의 집합이라고 생각할 수 있습니다.
말이 다시 어려워지는데, GoF의 예시로 생각하면
컴파일러는 아시다시피 여러 과정을 거쳐서 컴파일을 수행하는데요.
스캐닝, 파싱, AST트리 생성 등등 과정을 거치기 때문에 각 각의 기능을 위해
클래스로 분해해서 만드는게 자연스럽게 됩니다.
스캐닝을 하는 클래스, 파싱을 하는 클래스, 트리를 생성하는 클래스로요
그래서 가상의 컴파일러 서브시스템을 구성한다면 아래와 같은 클래스로 만들 수 있겠어요
그런데, IDE에서 컴파일을 실행시켰을 때, 컴파일이 실패된 이유에 대해서 사용자에게
알려주고자 한다면 어떻게 해야할까요?
IDE라는 시스템이 컴파일 하는 책임을 맡은 컴파일러 서브시스템에게 이에대한 정보를 얻어야할 것입니다.
여기서 조금 예제에 대해 이해해주셔야할 부분은
IDE는 독립적으로 존재하는 컴파일러(GCC, Mingw)를 단순히 사용하기 때문에
스캐닝, 파싱 등등의 절차에 대해 전혀 알지 못하지만, 이 예제에서는 설명의 용이성을 위해
IDE 시스템이 컴파일 기능을 포함하고 있는것으로 가정합니다
그러면 위와같이, 컴파일 에러가 발생할 수 있는 컴파일러 서브시스템에 의존해야할거에요
여기서 생길 수 있는 문제가 무엇일까요? 저는 아래와 같이 생각합니다.
이제 FACADE 를 적용시킨다면 아래처럼 바꾸면서 문제를 해결할 수 있습니다!
위와같이 바꾼다면, 앞에서 다루지는 않았지만 Compile 하는 기능자체도
Scanner.method() -> parser.method() -> ProgramNode.method() .. -> .. -> 컴파일 끝!
처럼 IDE 시스템에서 일일히 컴파일 서브시스템의 어떤 클래스의 어떤 메소드를 어떤 순서로
실행해야하는지 알 필요 없이, compile() 만 호출하면 되는것이죠
컴파일 에러를 확인하는 예시는 어떨까요?
더 이상 컴파일러 서브시스템에서 어떤 클래스가 에러를 만들어내는지 알 필요 없이
getCompileErr()를 호출해보면 알 수 있겠습니다.
여기서 패턴이란 FACADE외에 COMMAND, INTERPRETER, STRATEGEY 등을 의미합니다
FACADE패턴은 서브시스템이 제공하고자 하는 것만 제공할 수 있기 때문에
다른 서브시스템이 이 서브시스템내의 여러 메소드를 직접 호출할 일이 없어지기에
디버깅, 성능튜닝 및 의존성 감소의 효과를 얻을 수 있습니다
(2)번과 매우 유사한 장점입니다
FACADE로 묶어놓았기 때문에
여기서 얻게되는 장점이 있는데, 컴파일 의존성이 매우 줄어들게 됩니다.
다른 서브시스템의 FACDE를 사용하는 서브시스템은 FACADE의 인터페이스만 알기에
FACADE내에서 작동하는 클래스들이 수정되었을 때, FACADE만 새로 컴파일해줄 뿐
FACADE를 사용하는 다른 서브시스템의 재컴파일이 필요하지 않습니다
`