Eternity's Chit-Chat

aeternum.egloos.com



진화적인 설계-1.우리는 실패하고 있다 3부 Evolutionary Design

패턴과 패턴 언어
Ward Cunningham과 Kent Beck이 Christopher Alexander 의 패턴 개념을 소프트웨어 개발 커뮤니티에 소개한 이후 패턴은 항상 소프트웨어 개발 영역의 중요한 화두가 되어 왔다. GOF가 저술한 “Design Patterns”에 의해 패턴이 대중화된 이후 소프트웨어와 관련된 패턴을 다루는 수많은 저작물이 쏟아져 나왔으며 그에 비례해 패턴의 정의 역시 다양하고 풍부해져 왔다. 따라서 패턴이라는 거대한 숲 속에서 길을 잃지 않기 위해서는 패턴의 정의보다는 패턴이라는 용어 자체가 풍기는 미묘한 뉘앙스를 이해하는 것이 중요하다.

패턴이란 무엇인가를 논의할 때면 반복적으로 언급되는 몇 가지 핵심적인 특징이 존재한다.

  • 일반적으로 패턴은 반복적으로 발생하는 문제에 대한 해법의 쌍으로 정의된다.
  • 패턴을 사용함으로써 이미 알려진 문제와 이에 대한 해법을 문서로 정리할 수 있으며, 이 지식을 다른 사람과 의사 소통할 수 있다.
  • 패턴은 추상적인 원칙과 실제 코드 작성 사이의 간극을 메워주며 실질적인 코드 작성을 돕는다.
  • 패턴의 요점은 패턴이 실무에서 탄생했다는 점이다.

글을 쓰고 있는 지금 이 시간에도 여전히 많은 사람들이 다양한 각도에서 패턴의 개념을 정립하고 있다. 개인적으로 가장 적절하다고 생각되는 패턴의 특징은 Martin Fowler의 “Analysis Patterns”에서 발췌한 다음 단락에 함축되어 있다.

내가 사용하는 패턴 정의는 하나의 실제 컨텍스트에서 유용하고 다른 컨텍스트에서도 유용할 것이라고 예상되는 아이디어이다. 어떤 것도 패턴이 될 수 있기 때문에 아이디어라는 용어를 사용한다. 패턴은 “GOF” 패턴에서 이야기하는 것처럼 협력하는 객체 그룹일 수도 있고, Coplien의 프로젝트 조직 원리일 수도 있다. 실제 컨텍스트(practical context)라는 용어는 패턴이 실제 프로젝트의 실무 경험에서 비롯되었다는 사실을 반영한다. 흔히 패턴을 ‘발명했다’라고 하지 않고 ‘발견했다’라고 이야기한다. 모델의 유용성이 널리 받아들여지는 경우에만 패턴으로 인정할 수 있기 때문에 이 말은 타당하다. 실무 프로젝트가 패턴 보다 먼저지만 그렇다고 해서 실무 프로젝트의 모든 아이디어가 패턴인 것은 아니다: 패턴은 개발자들이 다른 컨텍스트에서도 유용할 것이라고 생각하는 어떤 것이다.

- Martin Fowler, Analysis Patterns

패턴은 한 컨텍스트에서 유용한 동시에 다른 컨텍스트에서도 유용한 ‘아이디어’다. 일반적으로 패턴으로 인정을 받기 위한 조건으로 삼요소 규칙(Rule of Three)을 언급한다. 이 규칙에 따르면 어떤 패턴 후보를 최소한 세 가지의 서로 다른 시스템에 적용했을 때 특별한 문제 없이 유용하고 효과적으로 사용할 수 있을 경우에만 패턴 목록에 추가할 수 있다.

패턴이 지닌 가장 큰 가치는 경험을 통해 축적된 실무 지식을 효과적으로 요약하고 전달할 수 있다는 점이다. 패턴은 경험의 산물이다. 책상 위에서 탄생한 비실용적인 이론이나 원리와 달리 패턴은 치열한 실무 현장의 역학관계 속에서 검증되고 입증된 자산이다. 따라서 초보자라고 하더라도 적절한 패턴을 익히고 적용함으로써 유연하고 품질 높은 소프트웨어를 개발할 수 있다.

이론과 원리는 추상적인 것이며 경험을 통한 건강한 피드백 없이는 깊이 있는 통찰에 이를 수 없다. 이론은 패턴을 지지하고 패턴은 이론의 존재 이유를 증명한다. 이론과 패턴의 피드백 루프는 학계와 실무 영역 사이의 괴리를 해소할 수 있는 한 가지 방법을 제시한다.

패턴은 지식 전달과 커뮤니케이션의 수단으로 활용될 수 있기 때문에 패턴에서 가장 중요한 요소는 패턴의 “이름”이다. 패턴의 이름은 커뮤니티가 공유할 수 있는 중요한 어휘집을 제공한다. 잘 알려진 이름을 사용함으로써 인터페이스를 하나 추가하고 이 인터페이스를 구체화하는 클래스를 만든 후 컨텍스트 객체의 생성자나 SETTER에 할당함으로써 런타임 시에 알고리즘을 바꿀 수 있도록 하자는 다소 장황한 대화가 STRATEGY를 적용하자는 단순한 대화로 바뀐다. 패턴의 이름은 높은 수준의 대화를 가능하도록 하는 원천이며 Alastair Cockburn이 지적한 불완전한 커뮤니케이션을 극복하기 위해 공유 경험을 자극할 수 있는 한 가지 방법을 제공한다.

Martin Fowler가 언급한 것처럼 패턴의 범위가 소프트웨어 개발과 직접적인 연관성을 가진 분석, 설계, 구현 영역만으로 한정된 것은 아니다. 다양한 크기의 프로젝트 조직을 구성하는 방법, 프로젝트 일정을 추정하는 방법, 스토리 카드나 백로그를 통해 요구사항을 관리하는 방법과 같이 반복적인 규칙을 발견할 수 있는 모든 영역이 패턴의 대상이 될 수 있다.

패턴은 홀로 존재하지 않는다. 특정 패턴 내에 포함된 컴포넌트와 컴포넌트 간의 관계는 더 작은 패턴에 의해 서술될 수 있으며, 패턴들을 포함하는 더 큰 패턴 내에 통합될 수 있다. Christopher Alexander는 연관성 있는 패턴들의 집합들이 모여 하나의 패턴 언어(Pattern Language)를 구성한다고 정의하고 있다. 패턴 언어는 연관된 패턴 카테고리뿐만 아니라 패턴의 생성 규칙 및 패턴 언어에 속한 다른 패턴과의 관계 및 협력 규칙도 포함한다. POSA1에서는 언어라는 용어가 지닌 제약 조건을 완화하기 위해 패턴 시스템(Pattern System)이라는 특수한 용어의 사용을 제안하기도 했으나 현재 두 용어는 거의 동일한 의미로 사용되고 있다.

분석 패턴과 디자인 패턴, 그리고 도메인 모델
패턴을 분류하는 가장 일반적인 방법은 패턴의 범위나 적용 단계에 따라 아키텍처 패턴(Architecture Pattern), 분석 패턴(Analysis Pattern), 디자인 패턴(Design Pattern), 이디엄(Idion)의 4가지 범주로 분류하는 것이다. 4가지 패턴 범주 중에서 가장 널리 알려진 것은 디자인 패턴(Design Pattern)이다. 디자인 패턴은 특정 정황 내에서 일반적인 설계 문제를 해결하며, 통신하는 컴포넌트들 간에 반복적으로 발생하는 구조를 서술한다. 디자인 패턴은 중간 규모의 패턴으로, 특정한 설계 문제를 해결하는 것을 목적으로 하며 프로그래밍 언어나 프로그래밍 패러다임에 독립적이다.

디자인 패턴의 상위에는 소프트웨어의 전체적인 구조를 결정하기 위해 사용할 수 있는 아키텍처 패턴(Architecture Pattern)이 위치한다. 아키텍처 패턴은 미리 정의된 서브시스템들을 제공하고, 각 서브시스템들의 책임을 정의하며, 서브 시스템들 간의 관계를 조직화하는 규칙과 가이드라인을 포함한다. 아키텍처 패턴은 구체적인 소프트웨어 아키텍처를 위한 템플릿을 제공하며 디자인 패턴과 마찬가지로 프로그래밍 언어나 프로그래밍 패러다임에 독립적이다.

디자인 패턴의 하위에는 특정 언어에 종속적인 이디엄(Idiom)이 위치한다. 이디엄은 특정 프로그래밍 언어에만 국한된 하위 레벨 패턴으로, 주어진 언어의 기능을 사용해서 컴포넌트, 혹은 컴포넌트 간의 특정 측면을 구현하는 방법을 서술한다. 이디엄은 언어에 종속적이기 때문에 특정 언어의 이디엄이 다른 언어에서는 무용지물이 될 수 있다. 예를 들어 C++의 COUNT POINTER 이디엄은 가비지 컬렉션 메커니즘을 이용하는 Java에서는 사용되지 않는다.

아키텍처 패턴, 디자인 패턴, 이디엄이(반드시 그런 것은 아니지만) 주로 기술적인 문제를 해결하는데 초점을 맞추고 있다면 분석 패턴(Analysis Pattern)은 도메인 내의 개념적인 문제를 해결하는데 초점을 맞추고 있다.

분석 패턴은 업무 모델링 시에 발견되는 공통적인 구조를 표현하는 개념들의 집합이다. 분석 패턴은 단 하나의 도메인에 대해서만 적절할 수도, 여러 도메인에 걸쳐 적용이 가능할 수도 있다.

- Martin Fowler, Analysis Patterns

객체 지향 패러다임의 가장 큰 장점은 도메인과 소프트웨어 간의 표현적 차이(representation gap)를 줄일 수 있다는 점이다. 객체 지향 기술을 사용하면 분석, 설계, 구현에 이르는 전 단계에 걸쳐 단일 모델을 사용할 수 있다. 이를 모델-주도 설계(Model-Driven Design)라고 한다.

분석 패턴과 관련된 가장 큰 오해는 분석 패턴이 도메인 모델링 단계에서만 제한적으로 사용 가능하고 설계 및 구현 단계와는 무관하다고 생각하는 점이다. 이러한 오해의 배경에는 분석/설계/구현이 완전히 분리된 별개의 작업이라는 오래된 미신이 한 몫을 하고 있다. 분석 패턴은 개념 모델링에 한정된 것이 아니다. 모델-주도 설계 원리에 따라 분석/설계/구현 전 단계에 걸쳐 하나의 개념 모델을 사용하기 위해서는 분석 패턴을 선택하는 시점부터 효과적인 구현 방법을 함께 고려해야 한다. Martin Fowler는 이에 대해 다음과 같이 언급하고 있다.

분석 기법은 소프트웨어 기술에 독립적일 것을 의도한다. … 실제로는 이와 같은 순수성을 달성하는 것은 불가능하다. 나는 전적으로 문제에 초점을 맞추는 매우 개념적인 모델을 작성하기 위해 노력했지만 사용하는 기술이 객체-지향이기 때문에 분석 모델은 소프트웨어 설계 접근방법을 반영하고 있다.

- Martin Fowler, Analysis Patterns

패턴은 출발점이지 목적지가 아니다. 도메인에 적합한 분석 패턴을 출발점으로 삼아라. 하지만 분석 패턴이 사용하고 있는 기술이나 프레임워크에 적합하지 않다면 목적에 맞추어 이를 수정하라. 구현 모델과 일치하도록 모델을 수정하고, 수정하고, 또 수정하라.

디자인 패턴의 목적은 기술적인 이슈를 해결하는 것이다. 분석 패턴의 목적은 도메인의 이슈를 해결하는 것이다. 디자인 패턴을 적용할 컨텍스트를 정하는 중요한 요인은 도메인에 내포된 본질적인 긴장감이 아니라 기술적인 압력이다. 그렇다고 해서 디자인 패턴을 도메인 모델링에 적용할 수 없다는 말은 아니다.

“Design Patterns”에 소개된 패턴 중 일부 패턴만을 도메인(또는 분석) 패턴으로 사용할 수 있다. 이를 위해서는 디자인 패턴에서 강조하는 사항들을 도메인 패턴에 맞게 적절히 수정해야 한다. “Design Patterns”는 다양한 환경에서 공통적으로 발생하는 문제들을 성공적으로 해결하기 위해 사용되었던 설계 요소들의 목록을 제공한다. 디자인 패턴을 사용하는 동기와 패턴 그 자체는 순수하게 기술적인 용어를 사용해서 표현된다. 그러나 일부 설계 요소는 많은 도메인에서 마주치게 되는 일반적인 개념과도 부합되기 때문에 도메인 모델링과 도메인 설계를 아우르는 포괄적인 문맥에서도 사용할 수 있다.

- Eric Evans, Domain-Driven Design

그렇다면 어떤 경우에 디자인 패턴을 도메인 패턴으로 사용할 수 있을까?

COMPOSITE 패턴의 경우 모델과 구현 코드 모두에 적용 가능하며, 이처럼 모델과 구현 코드 모두에 적용 가능하다는 점이 도메인 패턴의 본질적인 특성이다. … 기술적인 문제에 대한 기술적인 해결책뿐만 아니라 개념적인 도메인에 관한 해결책을 제공해야 한다는 것이 디자인 패턴을 도메인 패턴으로 적용하기 위한 유일한 요구사항이다.

- Eric Evans, Domain-Driven Design

여기까지다. 패턴에 대한 간략하지만 지루한 설명은 이쯤에서 접기로 하자. 이제 패턴과 진화적 설계의 연관관계에 관해 살펴보기로 하자.


덧글

  • Outsider 2011/04/22 10:22 # 삭제

    좋은 글 잘 읽었습니다.
    다음편 기대하고 있겠습니다. ㅎ
  • 이터너티 2011/04/27 00:55 #

    Outsider님 안녕하세요.
    Outsider님 블로그에 작년 KSUG 세미나와 관련해서 좋은 평 적어 주신 점 감사 드립니다.
    다음 편도 최대한 빨리 정리해서 올리도록 할께요. ^^
  • 2011/04/28 13:18 # 삭제 비공개

    비공개 덧글입니다.
  • mangofever 2011/05/04 13:23 # 삭제

    다음편 완전 기대됩니다~!
  • 이터너티 2011/05/23 01:08 #

    글이 많이 늦어졌네요. ^^;;
    재미있게 읽으셨으면 좋겠습니다.
※ 로그인 사용자만 덧글을 남길 수 있습니다.