반응형
<출처: http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=33152 >
 마소 홈페이지에서 패턴이란 단어로 PDF 서비스를 검색하면 총 42개의 콘텐츠가 뜬다. 그럼에도 패턴은 꾸준히 기사거리가 되고 있다. 왜 그런 것일까? 널리 알려진 것처럼 철학에서 수학이 분리되었고, 수학은 다시 과학으로 나누어졌다. 이처럼 많은 사람들이 관심을 가지고 참여하는 학문들은 진화할수록 세분화된다. 패턴 역시 1995년 GoF가 『Design Patterns: Elements of Reusable Object-Oriented Software』란 책을 내면서 널리 알려지기 시작했다. 그 이후 세분화되어 분석영역의 패턴(Analysis Pattern), 구현 패턴(Implement Pattern), 테스트 유닛 패턴(Test Unit Patterns) 등 각각의 도메인 특화된 패턴들이 계속해서 나오고 있다. 혹자들은 이제 패턴의 홍수로 인해 패턴 사용이 오히려 더 힘들어지는 시기라고 이야기한다.

필자는 많은 영역의 패턴 중에서 GoF의 디자인 패턴만큼이나 일찍(1996년 Pattern-Oriented Software Architecture) 소개되어 해외에서는 많이 전파되었으나, 아직까지 우리나라에서는 확산되지 않은 아키텍처 패턴에 대해 이야기하고자 한다.

소프트웨어 아키텍처란?
족보(?)를 거슬러 올라가듯이 아키텍처 패턴은 소프트웨어 아키텍처에 대한 내용이고 소프트웨어 아키텍처의 유래는 많은 IT 용어들이 그렇듯이 건축의 아키텍처에서 유래되었다. 그 족보 순서대로 아키텍처란 무엇인지부터 살펴보자.

아키텍처의 영문 어원은 Architecture = archi(first, chief, govern) + tect(build)이다. 해석해보면 건물을 구축(build)할 때 전체적인 구조를 관리(govern)하는 것을 의미한다. 라틴어의 어원을 찾아보면 Architectura = Arch(큰, 우두머리) + Tectura(기술), 즉 큰 시스템을 구축할 때 구조를 관리하기 위한 기술을 의미한다. 그렇다면 소프트웨어 아키텍처란 무엇을 의미하는가?

‘소프트웨어 시스템을 구성하는 서브시스템과 컴포넌트, 그리고 그것들의 관계를 나타내는 용어이다.’
- Pattern-Oriented Software Architecture, Volume 1: A System of Patterns

‘아키텍처는 컴포넌트로 구체화된 시스템의 기본적인 조직이며 환경에 대한 관계이고 디자인과 진화를 이끄는 원리이다.’
- IEEE1471

‘소프트웨어 구성요소와 그들이 지니고 있는 특성 중에 외부에 드러나는 요소의 특성, 그리고 구성요소들 간의 관계를 표현하는 시스템의 구조나 구조체를 말한다’
- Software Architecture in Practice

몇몇 책에서 나온 소프트웨어 아키텍처에 대한 정의이다. 정의가 조금씩 다르지만 공통적으로 언급하고 있는 것은 소프트웨어 아키텍처란 시스템을 구성하는 구성요소(서브시스템, 컴포넌트)와 그들(구성요소) 간의 관계를 나타낸다는 점이다.

좀 어렵다면 더 쉽게 예로 <그림 2>를 들어보자. 좌측 그림은 학창시절 좋아했던 프라모델의 조립설명서이고, 우측은 스트럿츠의 아키텍처를 표현한 그림이다. 좌측 조립설명서에는 조립부품에 대한 정보(부품번호)와 서로 연결되는 정보(화살표)를 표기하고 있다. 우측에 익숙한 스트럿츠 아키텍처도 역시 다를 바가 없다. 구성요소에 대한 정보(명칭)와 연관된 구성요소끼리의 관계를 표시하고 있다. 이제 소프트웨어 아키텍처가 어떤 것인지 감이 왔을 것이다. 그렇다고 소프트웨어 아키텍처가 그림이라고 생각하면 안 된다. 구성요소와 관계를 설명하기 위한 텍스트, 표 등 어떠한 형태로든 가능하며 거의 모든 경우 혼합되어 사용된다.

왜 소프트웨어 아키텍처를 알아야 하는가?

드라마나 영화에서 연인들이 <그림 3>과 같은 퍼즐을 사서 함께 머리를 맞대고 맞추는 모습을 본 적이 있을 것이다. 만약 좌측의 16조각 퍼즐이라면 완성된(구성요소와 연관 관계를 표시한) 그림 없이 쉽게 해낼 수 있다. 너무 빨리 끝나 다른 놀이도 준비해두지 않으면, 자칫 연인이 지루해 할 수도 있다. 그러나 우측같이 5,000조각의 퍼즐이라면 사정은 달라진다. 완성된(구성요소와 연관관계를 표시한) 그림은 필수인 것이다. 잘못하면 서로에게 ‘퍼즐하나 못 맞추나’라는 식의 실망감을 안겨줄 수도 있으니 조심해야 한다. 소프트웨어 아키텍처 역시 규모가 작은 프로그램에서는 필요하지 않다. 그러나 복잡한 시스템이라면 성공적인 구축과 유지보수를 위해 반드시 필요하다.

아키텍처 패턴이란?

아키텍처 패턴이란 디자인 패턴과 마찬가지로 특정 문제를 해결하기 위해 반복되어 사용되는 솔루션을 문서화한 것이다. 단지 문제의 영역이 설계(디자인)가 아닌 아키텍처라고 생각하면 된다. 나무를 보느냐, 숲을 보느냐의 차이인 셈이다.

아키텍처 패턴은 소프트웨어 시스템의 구조를 체계적으로 구성하기 위한 기본적인 스키마를 제시한다. 아키텍처 패턴에는 미리 정의된 서브시스템을 제공하고 각각의 아키텍처 패턴간의 책임을 명시하며 패턴들 사이의 관계를 조직화하는 규칙과 가이드라인을 포함하고 있다.

즉, 소프트웨어 시스템의 전체 구조를 나타내는 조감도이면서 구성요소들에 대한 설명서이기도 하며, 구성요소들 사이의 관계를 조직화하는 규정집이기도 하다. 아키텍처 패턴은 아키텍처는 아니나 시스템의 유용한 이미지를 전달해준다. 패턴의 또 다른 유용한 측면은 품질 속성을 명확히 보여준다.

왜 아키텍처 패턴을 알아야 하는가?

아키텍트(아키텍처를 총책임지는 사람)는 곧 잘 오케스트라의 지휘자와 비교된다. <그림 5>는 유명한 지휘자 카라얀의 지휘 모습을 보여준다. 카라얀은 원래 피아니스트로서의 길을 가려 했다. 그러나 그는 그 분야에서 성공할 가능성이 희박하다는 것을 느끼고 있던 차에 은사였던 파움가르트(BernhardPaum gartner)의 조언으로 지휘자의 길을 택한다.

카라얀이 지휘를 공부하면서 그의 인생엔 많은 행운이 잇따르는데 다름 아니라 당시 빈 국립가극장의 건물 관리자 겸 감독관이었던 사람이 바로 카라얀의 숙부였다. 숙부는 조카에게 유명한 지휘자의 연주회나 비공개 연습을 들을 수 있도록 해주었다. 거장들의 모습을 가까이 보면서 그는 많은 것을 배울 수 있었다.

여러분들이 아키텍처 패턴을 알고 사용한다는 것은 카라얀의 경우처럼 좋은 숙부가 없이도 훌륭한 아키텍트의 노하우를 배울 수 있다는 것이다. 다시 말하면 거장들이 이미 사용해 구축한 시스템이 존재하는 검증된 아키텍처를 이용할 수 있는 것이다. 개발에서 설계를 하게 되고 그러면서 디자인 패턴을 공부했듯이, 전체적인 소프트웨어의 시스템을 다루고자 할 때 아키텍처 패턴은 큰 도움이 될 것이다.

음악계에 재미있는 에피소드가 하나 있다. 또 다른 유명한 지휘자안 프란츠 샬크(F. Schalk 1863-1931)가 오케스트라를 객석에서 감상할 때의 일이었다. 연주가 무르익어가자 무의식적으로 눈을 감았다. 그랬더니 옆에 앉아있던 한 남자가 가만히 속삭였다. "그것은 현대 회화를 볼 때만 그렇게 하는 것입니다. 여기서는 귀를 막아야 해요."

모두가 아키텍처 패턴을 상세히 알아야 할 필요는 없지만, 최소한 다른 사람과의 대화나 전체 시스템에서 자신이 맡은 바를 이해할 수 있는 정도는 알고 있어야, 귀를 막거나 눈을 감는 사람이 되지 않는다.

[아키텍처 패턴의 장점]
- 검증된 아키텍처이다.
- 구축 전에 시스템의 특성에 대해 시뮬레이션할 수 있다.
- 기존 시스템을 쉽게 이해할 수 있다.   

아키텍처 패턴과 디자인 패턴
앞에서부터 디자인 패턴과 아키텍처 패턴을 계속 묶어서 이야기해왔다. 이쯤에서 명확히 서로간의 관계를 정리하도록 하자. 두 가지 모두는 소프트웨어 개발에 있어서 반복되는 문제들에 대한 해법이라는 점에서 동일하다.

하지만, 디자인 패턴이 프로그램의 설계에서 나타나는 반복적인 문제를 다루는 반면 아키텍처 패턴은 소프트웨어 시스템 전체적으로 영향을 미치는 사안들에 대한 해결 방법이다. <표 1>로 간단히 둘의 차이점을 정리해보았다.

예를 들면 ‘파이프&필터’라는 아키텍처 패턴이 있다. 이 패턴의 장점 중 하나는 동시 개발이 가능하다는 점이다. 필터 또는 파이프 단위로 나누어 개발 가능하기 때문에 병렬적 개발이 가능하다. 하지만 디자인 패턴 중에는 이런 장점을 가진 패턴이 존재하지 않는다.

이는 디자인 패턴은 설계 문제에 있어서의 해결책이기 때문이고, 아키텍처 패턴은 소프트웨어 시스템 전반에 관한 문제 해결이기 때문이다. 따라서 아키텍처 패턴은 디자인 패턴과 달리 조직의 구조나 개발 프로세스의 효율성까지도 포함한다.

둘은 이렇게 다루는 문제의 영역이 다르지만, 곧 잘 어울려 다닌다. 아키텍처 패턴의 구성은 디자인 패턴들로 이뤄지는 경우가 많다. 그래서 둘 사이의 관계를 Composit Pattern으로 표현할 수 있다. 아키텍처 패턴의 구성요소와 구성요소 사이의 관계를 반드시 디자인 패턴으로 해야 하는 것은 아니다. 하지만 앞으로 나올 예제에서도 볼 수 있듯이 둘은 함께 사용되는 경우가 많다.

아키텍처 패턴과 디자인 패턴간의 관계 예제
『Head First Design Patterns』에 나오는 예제로 아키텍처 패턴과 다지인 패턴 간의 관계를 설명하고자 한다. 예를 들어 보자. 한 개발회사에서 묘하게 DJ오디오 시스템과 심장 박동기의 공통점이 많음을 발견하고 MVC 패턴을 이용해 두 가지를 동시에 개발하기로 했다.

DJ오디오 시스템에서는 아이팟이 모델 역할을, 스크래치가 컨트롤러 역할을 맡고 뷰 컴포넌트의 역할은 스피커이다. 심장 박동기에서는 모델은 내부적으로 아날로그(박동)를 디지털(화면에 보이는 수치, 그래프)로 바꾸어주는 부분이고, 컨트롤러는 측정 대상과 연결되는 입력단자가 될 것이다.


이제 두 가지 시스템을 전체적인 UML 그림으로 보자.

MVC 중 VIEW와 Model 관계는 모델의 변경에 따라 자동으로 화면을 바꿔주기 위해 Observer Pattern으로 이뤄져 있다. 플레이어는 작동하는데 음악이 안 나오는 DJ오디오 시스템이나 심장 박동수가 표시되지 않는 심장 박동기를 누가 사겠는가?

같은 시스템이 설정에 따라서 DJ오디오 시스템일 수도 있고, 심장 박동기가 될 수도 있다. 그 때마다 원하는 기기로 사용하기 위해 모델 컴포넌트를 교체할 수 있어야 한다. 그래서 모델에는 Strategy Pattern이 적용되어 있다.

뷰 컴포넌트는 복합적인 화면을 쉽게 구성하기 위해 Composite Pattern을 사용해 구현되어 있다.

하나의 MVC 패턴의 구성요소인 모델과 뷰는 각각 Strategy Pattern과 Composite Pattern을 이용했고 뷰와 모델의 연결에는 Observer Pattern을 사용했다. 이렇듯 아키텍처 패턴에서 이야기하는 구성요소나 구성요소 간의 관계에 대한 규칙을 만족시키기 위해 디자인 패턴을 이용하는 경우가 많다.

이제까지 아키텍처 패턴에 대해 설명했다. 왜 우리가 아키텍처 패턴을 알아야 하는지를 따져보고 디자인 패턴과의 공통점과 차이점에 대해 살펴봤다. 큰 건물을 지을 때처럼 큰 시스템을 구축할 때는 아키텍처가 필요하다. 시스템의 요구사항에 맞는 아키텍처를 찾기 위해 아키텍처 패턴을 사용한다. 아키텍처 패턴은 실제 구현을 완료하지 않고도 시스템의 특성을 예측 가능하게 해주는 유용한 지식이다. 아키텍처의 세부 설계는 디자인 패턴을 이용할 수 있고, 많이 그렇게 사용한다. 디자인 패턴이 여러분의 많은 고민을 해결해주었듯이, 아키텍처 패턴도 그럴 수 있기를 기원한다.

MVC 패턴이란?
대표적인 아키텍처 패턴의 하나로 시스템 전체를 Model과 View, Controller 세 개의 컴포넌트로 나누어서 각 부분의 변경 영향도를 최소화하기 위한 패턴이다. Model 컴포넌트는 핵심 데이터와 기능을 캡슐화한다. 모델은 특정 출력 표현 방식이나 특정 입력 동작에 영향을 받지 않는다.

뷰 컴포넌트는 사용자에게 정보를 디스플레이한다. 뷰는 모델로부터 데이터를 얻는다. 모델로부터 제공된 데이터는 다양한 뷰를 통해 표시될 수 있으며, 각 뷰마다 컨트롤러 컴포넌트 하나씩 연결된다. 컨트롤러 컴포넌트는 사용자의 입력, 특정 이벤트 등을 서비스 요청으로 변환한다. 사용자는 오직 컨트롤러를 통해서만 시스템과 상호작용한다.

 

 

DJ오디오 시스템과 심장 박동기에 적용된 디자인 패턴
본문 예제에 등장하는 디자인 패턴에 대해 간단하게 설명하고자 한다. 각 패턴에 대한 자세한 내용은 참고자료에 나오는 「Design Patterns: Elements of Reusable Object-Oriented Software」 또는 「Head First Design Patterns」을 참고하면 된다.

Observer Pattern
두 객체 사이의 의존성 때문에 한 객체의 상태가 변경되면 자동적으로 관련된 객체들에게 알려주기 위한 설계이다. 우리가 다른 사람의 블로그를 매일 같이 들어가서 새로운 아티클이 등록되었는지 살펴볼 필요 없이 RSS를 등록하면 새 글이 올라왔을 때, 자동으로 알려주는 것과 같다. 여기서는 아이팟에 의해 다음 음이 해석되면 스피커에게 자동으로 알려주는 용도로 사용하고 있다.

Strategy Pattern 

같은 알고리즘들을 각각 캡슐화해 서로 호환 가능하게 만드는 설계이다. 클라이언트에 따라서 독립적으로 원하는 알고리즘을 사용할 수 있다. 전투기 게임에서 파워를 먹을 때마다 한 번에 발사되는 미사일의 개수와 모양이 달라진다. 이렇게 동일한 행위(미사일 발사)를 다른 방법(개수와 모양)으로 선택 가능하게 해주는 설계이다. 여기서는 음의 해석을 음악으로 볼 것인지, 심장 박동으로 볼 것인지 선택 가능하도록 하기 위해 사용되고 있다.

Composite Pattern
부분과 전체 구조가 트리 형식으로 표현되는 조립 객체를 Composite Object라고 한다. 클라이언트가 조립 객체나 개별 객체나 모두 동일하게 취급할 수 있도록 해준다. 문서를 작성하게 되면 글상자를 이용하기도 한다. 글상자는 문서와 동일하게 안에 텍스트나 그림을 넣을 수 있다.

이렇게 워드프로세서를 사용자 입장에서는 글상자가 문서의 부분이지만 문서와 동일하게 취급할 수 있게 해준다(글 상자 안에 텍스트를 입력하거나 그림을 삽입하는 방법이 다르다면 얼마나 불편하겠는가). 여기서는 사용자 UI를 구성함에 있어 모든 UI 파트를 Graphics라는 유형으로 단일 취급할 수 있게 사용하고 있다.


참고자료
1. Pattern-Oriented Software Architecture, Volume 1: A System of Patterns, Frank Buschmann, WILEY, 1996. 8
2. Software Architecture in Practice (2/E), Paul Clements, Addison-Wesley Professional, 2003. 4
3. IEEE 1471 국제표준(IEEE Recommended Practice for Architectural Description of Software-Intensive Systems)
4. Head First Design Patterns, Kathy Sierra, 2004. 10 
5. Pattern-Oriented Analysis and Design: Composing Patterns to Design Software Systems, Sherif M. Yacoub
6. Design Patterns: Elements of Reusable Object-Oriented Software, JOHN VLISSIDES, 1995. 8
7. [GoF] 패턴 이야기 - GoF Pattern Overview (손영수) -
http://www.devpia.com/NET2/EvaCast/Lecture/?cu=view&r=122



반응형
<출처: http://www.imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=33150 >
 새로운 것을 접하고 활용하는 과정에는 일정한 캐즘(chasm)이 존재한다. 캐즘이란 초기에 접하는 시점에서 그것을 활발히 사용하는 시점으로 넘어갈 때 느끼는 과도기적 현상을 설명한 마케팅 용어로, 흔히 일정하게 진행이 정체되거나 진행이 후퇴되는 것처럼 느껴지는 진행 단절 현상으로 나타난다.

프로그래머는 새로운 언어를 학습하는 과정과 새로운 프레임워크를 배우는 것 사이에서 비슷하지만 다른 캐즘을 느끼고, 그로 인한 스트레스를 받는다. 언어를 학습할 때는 대부분 몇 개의 기본적인 키워드와 확장 라이브러리, 컴파일러 및 코드 작성 환경에 대해 적응한 후 학습하고 있는 주 교재의 연습 문제나 자신이 잘 알고 있는 문제를 풀어보는 것으로 시작한다. 처음엔 대부분의 기본 키워드의 동작이나 확장 함수에 익숙하지 않아 느리게 학습이 진행되고 거기에 캐즘이 존재하게 되지만 두세 번 같은 유형의 문제를 반복하게 되면 해당 키워드나 함수에 대해 곧 원활히 사용할 수 있는 능력을 갖게 된다. 훗날 다른 부분을 학습할 때도 원활하게 기존에 배웠던 내용을 응용해 사용할 수 있으며 구현을 자유자재로 부릴 수 있게 된다.

프레임워크를 처음 학습할 때는 언어를 학습할 때처럼 예제부터 다루는 방법을 사용하기도 하지만, 먼저 프레임워크가 커버하는 문제 해결 범위와 용도에 대해 살펴본 후, 아키텍처와 내부 디자인, 프레임워크의 기능 중 수정하거나 첨부할 수 있는 부분과 없는 부분, 그리고 다양한 상황에 맞는 예제를 보게 된다. 그 다음 간단한 예제를 만드는 기능을 설명해 놓은 도움말과 장문의 레퍼런스 설명문, 그리고 마법사가 만들어 놓은 코드에 대한 이해를 먼저 한 다음 예제를 작성하는 순으로 접근하게 된다. 이러한 과정은 프레임워크에 대한 감을 잡기 전까지 캐즘으로 나타나게 되며, 프레임워크 학습을 저해하고 기피하게 되는 원인이 되기도 한다.

프레임워크는 일반적으로 문제를 풀기 위한 재사용 가능한 구현뿐 아니라 코드 구조와 재사용 가능한 디자인이 포함되어 있다. 따라서 전통적인 애플리케이션을 개발하는 방법과는 달리 프레임워크 기반으로 애플리케이션을 개발하기 위해서는 풀고자 하는 도메인 문제를 프레임워크의 구조를 이용해 풀어야 하며, 그러기 위해서는 애플리케이션의 구조를 프레임워크에 맞추기 위해 프레임워크의 기능과 디자인을 학습하는 과정이 반드시 필요하게 된다. 반대로 프레임워크를 개발할 때는 프레임워크의 기능을 쉽게 확장하고 이용할 수 있도록 해야 하며, 디자인을 쉽게 학습할 수 있도록 문서 및 레퍼런스를 제공해야 한다.

프레임워크 기반 애플리케이션의 과정을 도식화해 보면 <그림 1>과 같이 나타낼 수 있는데, 프레임워크 개발자는 프레임워크의 디자인 및 구현, 프레임워크로의 반영, 프레임워크 개선, 프레임워크의 문서화를 담당하며 애플리케이션 개발자는 프레임워크 반영, 프레임워크 이해 및 문서와 레퍼런스를 이용한 이해와 응용 부분을 담당하게 된다.

프레임워크를 이해하기 위한 패턴 언어
PLOP‘08 학회에 발표된 ‘Pattern for UnderstandingFrame works’ 논문에는 프레임워크를 애플리케이션에 적용하기 위해 이해하는 방법으로 다음과 같은 일련의 패턴 언어를 거친다고 기술하고 있다.

- 프레임워크 선택하기 (Selecting a framework)
- 프레임워크를 이용한 프로젝트 레퍼런스 만들기 (Instantiating a framework)
- 프레임워크 발전시키기(Evolving a framework)
- 프레임워크 학습 (Drive your learning)
- 사용 경험의 보전 방법 (Knowledge-keeping)
- 애플리케이션 도메인의 이해 (Understand the application domain)
- 프레임워크 아키텍처의 이해 (Understand the architecture)
- 프레임워크 내부 디자인의 이해 (Understand the design internals)
- 프레임워크 코드의 이해 (Understand the source code)

프레임워크를 구현할 때 무엇보다 중점적으로 집중할 부분은 애플리케이션에 공통적으로 나타나는 부분과 가변적으로 나타나는 부분을 구분하고 분석하는 일이다. 공통적인 부분은 다수의 애플리케이션에서 공통적으로 코드가 반복되게 되므로 프레임워크 안쪽으로 코드가 구현되어 있어 프레임워크 사용만으로 코드 재사용이 일어나도록 구현하는 것이 좋다. 가변적인 부분은 애플리케이션마다 가변적이기 때문에 프레임워크 내의 구현부를 쉽게 선택할 수 있도록 프레임워크 초기화 부분의 파라미터 등을 통해 기능 접근을 할 수 있도록 해야 하며, 만일 가변적인 부분을 프레임워크 내에서 모두 포함하지 못한다면 애플리케이션마다 특정한 상황의 구현을 프레임워크 코드를 대체해 커스터마이징할 수 있도록 위치를 제공해야 한다. 커스터마이징은 가상 함수의 특징인 훅 메소드 형태로 제공해주고 각각의 애플리케이션은 프레임워크에 존재하는 가변적인 코드의 위치를 훅 메소드로 파악해 공통적인 프레임워크의 기능에 도메인에 특화된 기능을 끼워 넣을 수 있도록 한다. 공통적으로 나타나는 변하지 않는 부분의 코드부를 프로즌 스팟(Frozen spots)이라 하며 도메인별로 재구현하는 빈도가 높은 부분의 코드부를 핫 스팟(Hot spots)이라고 한다. 프레임워크를 학습하고 사용할 때 또한 프레임워크의 프로즌 스팟과 핫 스팟을 구분하는 부분을 중점적으로 살펴봐야 한다.

프레임워크 선택하기
프레임워크를 사용하는 데는 다양한 이유가 있다. 예를 들어 MFC를 사용하는 것과 같이 특정 도메인 환경에서의 검증된 코드와 디자인을 활용하기 위해 적용할 때도 있고 애플리케이션을 구현하기에 반복적인 작업이 많이 들어가거나, 애플리케이션의 규모가 커질 경우 애플리케이션의 구현 부담을 프레임워크 적용으로 덜기 위해 프레임워크를 적용하기도 하며, 얼마 전 온 세상을 붉게 물들였던 루비 온 레일즈의 특징처럼 애플리케이션의 구현 기간이 짧아야 할 경우 기능이 미리 충분히 갖춰진 프레임워크를 이용해 릴리즈 일정을 빠르게 하려는 등의 이유로 프레임워크를 사용하게 된다. 이를 위해 먼저 프로젝트에 적용할 프레임워크를 선별하는 작업이 필요한데 선별 작업에 있어 몇 가지 고려할 사항이 있다.

먼저 도메인을 분석하는 작업과 프레임워크의 기능 분석 작업이 필요하다. 애플리케이션이 적용될 도메인을 분석하는 작업과 함께 프레임워크가 가지고 있는 해결 방법이 도메인 문제를 해결해줄 수 있는 애플리케이션을 구현하는 데 기능을 충분히 포함하고 있는지 살펴봐야 한다. 도메인을 분석하는 방법은 ‘애플리케이션 도메인의 이해’ 패턴이 도움이 될 수 있으며 프레임워크의 기능을 파악할 때는 프레임워크의 목적과 성격을 기술해 놓은 문서를 살펴보고 프레임워크의 주요 기능들을 확인하면서 프레임워크에 첨부된 활용 예제들을 살펴보면 도움을 얻을 수 있다.

또한 프레임워크 후보군들 가운데 각 프레임워크를 배우는 데 필요한 시간과 노력을 가늠해보고 적량해보는 작업이 필요하다. 애플리케이션의 개발 기간과 결과물의 품질은 총합인 비용을 두고 한쪽이 높아지면 한쪽이 낮아지는 트레이드 오프 관계에 있으므로 좋은 프레임워크라도 배우는 데 비용이 많이 든다면 프레임워크를 선택할 때 학습 비용을 고려한 선택이 이뤄져야 한다. 그 이유는 학습에 관련된 프레임워크의 문서화가 잘 되어 있는지 확인하는 것도 중요한데다 문서화가 잘 되어 있을수록 학습에 들어가는 비용은 낮아지기 때문이다. 마지막으로 프레임워크의 복잡도가 얼마나 되는지 확인하는 작업이 필요하다. 프레임워크 복잡도에 대한 이해를 위해 ‘프레임워크 아키텍처의 이해’ 패턴과 ‘프레임워크 코드의 이해’ 패턴이 사용되기도 한다.

프레임워크를 선택해서 학습하는 과정은 비용이 많이 들어가는 작업이며, 프로젝트에 적용된 후 중간에 적용한 프레임워크를 교체하는 작업은 경우에 따라 불가능할 정도로 비용이 많이 들어가는 작업이므로 프레임워크를 선택하는 작업은 신중하게 이뤄져야 한다.

프레임워크를 이용한 프로젝트 레퍼런스 만들기
적당한 선택 이후 프레임워크를 사용할 때는 다양한 경력과 경험을 가지고 있는 프로그래머들이 모여 작업하므로 일부 경험이 부족한 프로그래머의 경우 프레임워크를 원활하게 사용하게 될 때까지 기간이 소요되는 경우도 있고, 생소한 프레임워크를 접할 경우 프레임워크에 적응하는 기간과 프레임워크의 복잡도에 따른 학습 시간을 가져야 하는 경우도 있다.

프레임워크를 사용해 애플리케이션을 개발한다는 것은 프레임워크가 제공해주는 아키텍처를 바탕으로 도메인에 특화된 문제를 해결하는 뼈대를 만들고 프레임워크의 구현부에서 재사용하는 코드를 기본으로 도메인에 특화된 문제를 프레임워크 구조에 끼워 넣는 작업으로 진행되기 때문에 프레임워크의 구조 중 끼워 넣는 부분에 대한 정보를 얻고 알아가는 과정의 학습을 통해 프레임워크를 사용한다고 할 수 있다. 이때 프레임워크 코드에서 변하지 않는 프로즌 스팟 부분과 끼워넣을 수 있는 핫 스팟 부분을 구분할 수 있는 것이 중요하다.

프로즌 스팟과 핫 스팟을 구분하는 쉬운 방법은 프레임워크에 포함된 문서를 학습하는 것이다. 애플리케이션 개발자는 프레임워크의 문서에서 확장 포인트를 학습할 수 있다. 대부분의 프레임워크에 포함된 안내문서에는 프레임워크의 프로즌 스팟과 도메인 문제에 구현을 특화시켜 끼워 넣어야할 핫 스팟 구분에 대한 내용이 나와 있으며 특화시킬 코드에 대한 간략한 형태와 함께 이용할 수 있는 유틸리티 등을 소개하고 있다. 문서가 충분치 않다면 애플리케이션에서 프레임워크 코드와 연동되는 진입 부분의 코드부터 분석해서 프레임워크를 알아내면 확장 포인트를 찾을 수 있다.

프레임워크를 이용해 작업할 때, 레퍼런스와 프레임워크 코드만을 가지고 작업하는 것보다는 도메인에 실제로 사용할 수 있는 적당한 예제 단위로 레퍼런스를 구축해 놓으면 팀 단위 작업에서 공통으로 프레임워크를 사용할 때 더욱 효율성을 높일 수 있다.

프레임워크 발전시키기
프레임워크를 개발하는 개발자는 프레임워크가 여러 도메인에 적용됨에 따라 나타나는 문제를 해결해 프레임워크 코드와 디자인에 반영시켜야 하며 하드웨어의 변화, 운영체제 등의 환경 변화를 수용하면서 되도록 하위호환성을 가지게끔 프레임워크를 발전시켜야 한다. 프레임워크를 발전시킬 때, 프레임워크를 설명하는 문서와 첨부된 문서들은 프레임워크를 발전시킬 만한 이슈가 나오기 이전에 만들어진 경우가 많으므로, 대부분의 경우 도움이 되지 못한다.

프레임워크를 발전시키기 위해 프레임워크 유지 보수자는 소프트웨어 전문가일 뿐만 아니라 도메인 전문가 입장에서 문제를 바라볼 수 있어야 한다. 소프트웨어 전문가 입장에서 프레임워크 아키텍처를 살펴보고 프레임워크의 구성이나 어떻게 만들어졌는지, 그리고 목적이 무엇인지 정확하게 이해해야 하고, 도메인 전문가로서 현재 프레임워크가 발전할 수 있는 요수가 무엇인지 분석할 수 있는 능력이 있어야 한다. 소프트웨어 전문가가 아닐 경우 프레임워크의 목적과 구성을 잘못 이해해서 프레임워크의 수정 방향이 잘못 이뤄질 수 있다. 특히 눈앞의 도메인 문제만을 프레임워크에 적용시키려 하면 프레임워크의 목적이 변경되어 질 수 있으며 이때 ‘프레임워크 내부 디자인의 이해’ 패턴과 ‘애플리케이션 도메인의 이해’ 패턴이 정확한 판단을 하는 데 도움을 줄 수 있다.

프레임워크 학습
프레임워크 내부는 커다란 아키텍처 안에 많은 디자인 구조들이 들어가 있고, 디자인마다 다양한 코드들이 존재하게 된다. 일반적으로 애플리케이션은 시작 지점이 존재해서 실행하게 되고 따라서 실행 지점부터 애플리케이션의 수행을 알아본다면 애플리케이션의 분석을 쉽게 할 수 있지만, 프레임워크는 시작점이 없는 특징을 가지고 있기 때문에 일반 애플리케이션처럼 진입 전부터 분석하는 방법은 사용할 수 없다.

프레임워크를 분석하는 방법으로 하향식 방법(Top-down)과 상향식 방법(bottom-up)이 있다. 하향식 방법은 추상화된 레벨에서부터 분석을 시작하는데, 큰 그림을 먼저 잡고 목적을 파악한 다음 서서히 구현부로 내려오면서 프레임워크를 이해하는 방법을 의미하고, 상향식 구현 방법은 거꾸로 세부 구현부터 살펴보면서 점차 추상화된 레벨로 올라가면서 전체적인 구조를 파악하는 분석 방법이다. 두 가지 방법은 모두 장단점을 가지고 있기 때문에 개발자가 자신이 편한 방법으로 분석하면 되는데 대체로 프레임워크에 대한 경험이 많은 사람은 하향식 방법을 사용하면 빠르고 효율적이게 분석할 수 있다. 경험이 많은 개발자는 구현부에 만들어진 코드에 대한 대략적인 지식을 가지고 있으므로 추상화 단계를 보고 전체적인 구조를 쉽게 파악할 수 있기 때문이다. 다양한 상황에 대한 생각을 많이 하는 사람이나 전체적인 기능 파악을 먼저 하는 것을 선호하는 사람 또한 하향식 방법이 좋다. 반면 순차적으로 학습하기를 선호하고, 학습할 때 능동적으로 찾아 학습하는 경향이 있는 사람에게는 상향식 방법이 좋다.

사용 경험의 보전 방법
프레임워크를 애플리케이션에 적용하고, 도메인에 특화된 문제를 프레임워크에 끼워 넣는 작업 프레임워크의 아키텍처와 구조 학습이 선행된 다음에 가능한 작업이다. 이렇게 프레임워크 사용 작업을 반복하면 프레임워크 사용법과 주의사항들이 자연스럽게 학습되고 세부 구조를 쉽게 이해하게 되는데, 이렇게 생긴 노하우나 프레임워크 정보들은 단기간 내에 문서를 보거나 예제를 학습함으로써 얻을 수 없는 것들이 많다. 특히 특정 상황에서 프레임워크의 동작이나 특화된 디자인으로 인해 주의해야 할 점, 프레임워크를 이해하는 과정 중에서 생긴 노하우나 그밖에 프레임워크 관련 정보들에 대해서는 보존하는 것이 좋다.

프레임워크 사용 경험을 보전하는 가장 좋은 방법은 정보들에 대한 문서화하는 것이다. 프레임워크 사용 경험을 문서화시키고 실제 사용했던 코드나 테스트했던 코드들의 레퍼런스나 케이스를 정리하고 포함해 정보들을 문서화해 공유한다면 추후 다시 한 번 볼 수도 있고, 다른 개발자들에게 전파할 수 있다.

애플리케이션 도메인의 이해
프레임워크가 해결해줄 수 없는 애플리케이션 문제는 프레임워크를 적용한 후에 별도로 구현해줘야 하기 때문에 프레임워크를 선택할 때는 애플리케이션에서 구현할 내용들을 해결해줄 수 있는 범위가 어디까지인지 파악하는 것이 중요하다. 이때 도메인에 대한 지식이 부족한 상태라면 프레임워크의 선택을 잘못할 위험이 있으므로, 성공적인 프레임워크 선택에는 도메인의 문제를 잘 파악하고 있는 부분이 중요하게 작용한다. 프레임워크 선택 전 도메인 문제에 대한 지식이 부족한 상태라면 도메인 전문가의 조언을 받아서 도메인에 대한 정보를 확보할 필요가 있다. 전문가의 조언을 받으면서 프레임워크에 포함된 문서의 프레임워크 소개 내용이나 프레임워크가 가지고 있는 해결 방법의 범위와 목적을 알아 가면 해당 프레임워크가 도메인 문제를 푸는 데 적당한지 여부를 판단할 수 있다.

문서화와 예제가 충실하게 잘 갖춰져 있지 않은 프레임워크일 경우 정보를 얻기가 쉽지 않은데, 프레임워크에 대한 정보를 얻기가 여의치 않으면 프레임워크가 가지고 있는 컴포넌트의 이름이나 클래스 이름, 함수 이름들을 살펴보고, 이들을 문서에서 검색하거나 웹을 통해 검색하면 프레임워크의 정보에 대한 힌트를 얻을 수 있다. 이러한 분석을 하다보면 컴포넌트 간의 관계가 파악되는데, 이를 통해 프레임워크의 아키텍처에 대한 구조 정보를 얻을 수 있다. 이러한 구조 정보는 도메인의 적용 범위를 알아볼 때 유용하게 쓰인다.

프레임워크 아키텍처의 이해
프레임워크 기반의 애플리케이션은 프레임워크의 의도에 따라 애플리케이션의 구조가 결정된다. 따라서 프레임워크의 아키텍처는 애플리케이션에 직접적인 영향을 미치게 되므로 프레임워크의 아키텍처 구조를 이해하는 것은 애플리케이션의 흐름과 구조를 파악하는 것과 밀접한 관계가 있다. 구조를 파악하게 되면 프레임워크의 구현체를 재사용하기에 더 용이하며 컴포넌트끼리의 관계를 파악할 수 있으므로 빠르고 정확한 프레임워크 적용이 가능해진다. 화이트박스 프레임워크의 경우 구조를 파악하지 않은 채 상속을 통해 애플리케이션의 기능을 구현하다보면 컴포넌트 간의 관계나 프레임워크 아키텍처 상 맞지 않는 코드를 작성할 수 있으므로 프레임워크의 아키텍처를 파악하는 일은 중요하다.

<그림 4>의 경우 복잡한 네트워크 프레임워크의 아키텍처를 구성하는 패턴들을 나타내고 있으며 각 패턴들이 연결되어 있는 관계도를 도식화해 나타내고 있다. 이처럼 프레임워크의 아키텍처를 이해할 수 있는 문서가 있다면 쉽고 빠르게 구조를 파악하는 데 도움을 받을 수 있다. 아키텍처를 파악할 때는 글과 코드만으로는 한눈에 알아보기 어려운 경우가 많다. 때로는 리버스 엔지니어링 툴을 이용하면 프레임워크의 구조를 알아보는 데 도움을 받을 수도 있다.

프레임워크 내부 디자인의 이해
프레임워크의 아키텍처로 애플리케이션이 문제를 해결하는 방향을 잡는다고 한다면, 애플리케이션에서 도메인에 대한 문제를 유연하게 풀어나가는 것은 내부 디자인에 의해 결정된다. 주로 간단한 패턴들로 이뤄진 내부 디자인은 프레임워크의 확장성과 유연성이 실제적으로 구현되는 부분이기도 하며 프레임워크가 다수의 애플리케이션에 공통적으로 적용시킬 수 있는 특성과 코드를 재사용하는 특징 또한 이 내부 디자인을 통해 제공하게 된다.

실제로 프레임워크를 사용하는 데 있어서 단번에 이해할 수 없도록 복잡한 느낌을 주는 이유도 이 내부 디자인에서 오기 때문인데, 따라서 내부 디자인을 이해하는 것은 실제적으로 프레임워크를 사용하는 데 직접적인 영향을 줄 뿐만 아니라 프레임워크를 좀 더 다양하게 활용할 수 있는 요소를 제공하기도 한다.

애플리케이션에서 프레임워크를 적용하기 위해서 내부 디자인을 살펴볼 때는 그 내부 디자인이 화이트박스 프레임워크를 의도하는지, 블랙박스 프레임워크를 의도하는지 파악하는 것이 중요하다. 이러한 파악에는 특히 디자인 패턴에 대한 선행학습이 큰 도움이 되며, 디자인 패턴에서 말하는 패턴들의 장단점, 그리고 의도를 미리 알고 있다면 프레임워크를 어떤 식으로 사용해야 바람직하고 좋게 사용하는 것인지 판단하는 데 큰 도움이 된다. 프레임워크 내부 디자인을 이해하면 프레임워크에서 의도하는 프로즌 스팟과 핫 스팟의 위치를 파악할 수 있고, 코드의 흐름과 프레임워크를 구성하는 컴포넌트들의 관계를 정확하게 파악할 수 있으며, 프레임워크를 실제 애플리케이션에 적용하는 데 필요한 방법과 정보를 정확하게 알아낼 수 있다.

프레임워크 코드의 이해


프레임워크를 만든 개발자들은 다수 도메인 문제에 대한 많은 경험과 높은 프로그래밍 실력을 가지고 있는 경우가 일반적이다. 이러한 프레임워크 개발자들이 만들어 놓은 프레임워크 코드들은 경험이 부족한 개발자들이 보기에 올바른 코딩 방향과 좋은 코딩 습관을 길러주는데 좋은 본보기가 되는데, 이는 애플리케이션에 적용할 프레임워크를 이해하는 것뿐만 아니라, 프레임워크를 만든 프로그래머들의 프로그래밍 경험을 얻을 수 있는 좋은 기회가 된다.

 

프레임워크가 일반적인 애플리케이션 코드보다 이해하기가 힘든 이유는 일반적인 애플리케이션은 시작점과 종료점이 있는 반면에, 프레임워크는 애플리케이션과 다르게 시작하는 지점이 없기 때문일 것이다. 다시 말해 분석하는 시작점을 찾을 수 없어서 분석하기가 어렵게 느껴지는 경향이 있는 셈이다. 라이브러리와 프레임워크 사용의 가장 큰 차이점은 라이브러리의 경우 애플리케이션에서 구현체를 사용하기 위해 라이브러리의 기능을 호출하는 형태로 사용하지만, 프레임워크의 경우 반대로 프레임워크에 의도하는 구조에 따라 애플리케이션의 흐름이 운용된다는 것이다. 이는 라이브러리를 사용하는 일반 애플리케이션보다 프레임워크를 사용하는 애플리케이션의 코드 분석이 더 어렵게 만드는 이유가 되기도 한다.

프레임워크 코드를 이해하는 가장 좋은 방법은 프레임워크를 이용해 문제를 해결하는 예제를 분석하는 방법인데, 예제의 시작점부터 출발해서 문제를 해결하기 위해 프레임워크가 호출하는 진입점을 살펴보면 쉽게 코드를 분석할 수 있다. 프레임워크는 보통 예제문서와 다양한 도메인 환경에서 프레임워크를 사용하는 방법을 첨부하는데, 이러한 문서들은 프레임워크 코드 분석에 도움을 준다.

참고자료
1. Patterns for Understanding Frameworks (Nuno Flores, Ademar Aguiar) - PLOP’08
2. QoS Middleware Coursework (Douglas Schmidt) - http://www.cs.wustl.edu/~schmidt/cs396/index.html
3. Advanced Software Engineering - CSE870, Spring 2007
4. Testing framework-based software product lines = Raine Kauppinen



+ Recent posts