전문가들이 어떤 문제(problem)와 맞닥뜨렸을 때, 기존에 사용했던 해결책(solution)과는 완전히 다른 방법으로 그 문제에 접근하는 경우는 매우 드물다. 그들은 일반적으로 이미 해결해 본 문제들 중, 당면한 것과 유사한 문제를 찾아 당시의 해결방법을 당면한 문제 해결에 응용하곤 한다. 여기서 '유사한 문제'란 구체적이고 세세한 사항은 다를 수 있지만, 그 해결책이 가지는 핵심적인 방법은 같은 것을 말한다. 이런 일련의 과정을 효과적으로 수행하기 위해 만든 개념이 바로 패턴(pattern)이다. 패턴에서는 빈번히 발생하는 ‘문제'와 그 문제에 대한 '해법’을 쌍으로 구성해, 특정 문제에 대한 해법을 손쉽게 재활용 할 수 있도록하고 있다.
소프트웨어 영역에서 사용되는 '패턴'의 특징을 보면 다음과 같다.('패턴'이라는 개념은 소프트웨어 영역 뿐만 아니라 건축·경제 등의 분야에서도 사용된다.)
패턴은 특정한 상황(context)에서 반복적으로 발생하는 설계상의 문제와 그에 대한 해법을 제시한다. 많이 알려진 MVC 패턴에서의 문제는 UI가 쉽게 변할 수 있다는 것이다. 이 문제는 사용자와 컴퓨터가 상호작용해야 하는 소프트웨어를 개발할 때 흔히 대두되는데, 이런 문제를 해결하기 위해서는 책임(responsibility)을 엄밀히 구분하면 된다. MVC 패턴에서는 소프트웨어의 핵심 데이터와 기능을 UI로부터 분리하는 방법을 제시했다.
패턴은 이미 그 효과가 입증된 경험을 정리한 것이다. 패턴은 인위적으로 발명되거나 창조되는 것이 아니다. 경험 많은 전문가가 얻은 설계에 대한 지식을 모아, 재사용할 수 있는 형태로 정리한 것이 패턴인 것이다. 그렇기 때문에, 이미 많은 패턴을 숙지하고 있는 사람이라면, 패턴에 해당하는 문제의 해결책을 다시 찾을 필요 없이, 기존의 지식만으로도 즉각 설계에 그 해결책을 적용 할 수 있다. 극소수 전문가들끼리 비밀리에 전수하는 ‘비법(秘法)’과는 달리, 패턴은 누구나 공개적으로 사용할 수 있다. 즉, 패턴은 특정 상황에서 고품질 소프트웨어를 설계할 때, 전문가 수준의 지식을 누구나 쉽게 사용할 수 있게 해준다. MVC 패턴 역시도 수년 간 상호작용 시스템을 개발하며 얻은 경험을 정리한 것이라 할 수 있다.
패턴은 컴포넌트나, 단일 클래스, 객체 같은 수준보다 높은 단계의 추상 레벨에서 발견되고 정의된다. 대체로 패턴은 몇몇 컴포넌트, 클래스, 객체를 서술하며 그것들의 책임, 관계(relationship), 협력(cooperation)에 대한 내용을 상세히 정의한다. 모든 컴포넌트나 클래스, 객체들은 패턴이 해결하고자 하는 문제를 함께 풀어가는데, 단일 컴포넌트로 해결하는 것보다 훨씬 효과적이다. 실제로, MVC 패턴에서는 모델, 뷰, 컨트롤러라는 세가지 컴포넌트의 상호 협력에 대해 명시하고 있으며, 결과적으로 단일 컴포넌트로 만드는 것보다 유연하고 효과적인 시스템을 만들어내고 있다.
패턴은 설계 원칙에 대한 공통 어휘(vocabulary)와 공감대를 형성시켜준다. 패턴의 이름이 적절히 붙는다면, 설계 용어로 쉽게 사용할 수 있다. 패턴의 이름이 설계 용어로 사용되면, 설계에 대해 의견을 나눌 때, 그 효율성이 배가된다. 특정 문제에 대한 해법을 설명할 때, 패턴 이름만 알고 있다면 해법의 메커니즘을 복합하고 장황하게 설명하지 않아도 되기 때문이다. 해법의 어떤 부분들이 패턴의 어떤 컴포넌트에 해당하는지, 혹은 컴포넌트들 간의 어떤 관계가 패턴의 어느 부분과 관계 있는 것 인지만 설명하면 되는 것이다. 예를 들어, 패턴에 대해 익숙한 동료들끼리 “이 소프트웨어의 아키텍처에는 MVC 패턴을 적용합시다” 라고 말할 경우, 동료들은 이 애플리케이션의 기본 구조와 특성들을 부연 설명 없이도 쉽게 파악할 수 있게 된다.
패턴은 소프트웨어 아키텍처를 문서로 정리하는 방법이다. 패턴을 사용하면 특정한 문제에 대한 복안(腹案)을 쉽게 문서로 정리할 수 있는 것이다. 이런 점은 소프트웨어를 확장할 때도 매우 유리하게 작용한다. 소프트웨어를 확장할 때, 기존의 소프트웨어가 MVC 패턴에 맞게 설계되었다는 것을 알고 있다면, 새로운 기능이 모델, 뷰, 컨트롤러 중, 어떤 컴포넌트에 해당하는 확장인지 쉽게 파악할 수 있고, 기존의 설계 원칙에 어긋나지 않게 새로운 기능을 추가해 넣을 수 있기 때문이다.
패턴은 고유한 특성(property)을 제공해야 하는 소프트웨어를 개발할 수 있도록 도와준다. 패턴은 각 컴포넌트가 제공해야 하는 기능적인 골격을 제시하고 있다. 예를 들어 Peer-To-Peer 패턴은 프로세스간 통신에 대한 특성을 포함하고 있고, MVC 패턴은 UI의 가변성과 핵심 기능의 재사용성에 대한 특성을 포함하고 있다. 실제로 개발하고자 하는 소프트웨어가 프로세스간 통신을 필요로 한다면 Peer-To-Peer 패턴을, UI가 자주 변경된다면 MVC 패턴을 적용하거나 참고하면 보다 쉽게 소프트웨어를 설계개발 할 수 있다.
패턴은 복잡한 소프트웨어의 아키텍처를 구축하는 데 도움을 준다. 모든 패턴은 컴포넌트들과 그것들 사이의 역할 및 관계를 정의해 놓고 있다. 이런 패턴은 복잡한 설계를 위한 빌딩블록(Building-Block)으로 사용할 수 있는데, 이를 통해 이미 검증된 설계 방식을 응용하게 되어 설계에 들이는 시간은 단축하고, 그 질은 향상시킬 수 있다. 물론 많이 알려진 패턴이 항상 개발자 스스로가 고안한 해법보다 우수한 것은 아니지만, 설계 방안을 검토할 때 충분히 참고하거나 응용할만한 가치가 있다. 반면, 패턴은 문제 해결을 돕는 것이지, 완전한 해법을 제공하지는 않는다. 패턴이 특정 문제에 대한 해법의 기본 구조를 결정할지라도, 해법의 세부 내용까지 모두 정의하고 있지는 않다. 패턴은 특정 문제 유형의 일반적인 해법에 대한 스키마(scheme)만을 제공할 뿐이지, 사전에 미리 제조되어 그대로 가져다 쓰기만 하면 되는 완전한 조립식 모듈은 아닌 것이다. 그러므로 패턴을 적용하려는 개발자는 설계의 구체적인 세부 내용은 스스로 구현해야 한다. 패턴은 아키텍처 수준의 설계를 돕기 때문에, 패턴을 적용한 해법의 포괄적인 구조는 비슷할 수 있지만, 세부적인 내용에서는 상당히 차이가 날 수 밖에 없다.
패턴을 사용하면 소프트웨어 복잡성을 관리하는 데 유용하다. 모든 패턴은 해결하고자 하는 문제의 해법을 서술한다. 이때 해법에는 필요한 컴포넌트의 종류, 각 컴포넌트의 역할, 숨겨져야 하는 세부 구현, 노출되어야 하는 추상화 부분, 그리고 이것들이 동작하는 방법 등이 서술되어야 한다. 그렇기 때문에 어떤 패턴이 다루고 있는 문제와 맞닥뜨렸을 때, 문제에 대한 해법을 찾느라 시간 들여 골몰할 필요가 없다. 패턴을 올바르게 구현하면, 그 패턴이 제공하는 해법은 자연스레 따라오는 것이다.