디자인 패턴의 정의
패턴(Pattern)이란?
특정 컨텍스트 내에서 주어진 문제의 해결책이다.
- 컨텍스트(Context)
- 패턴이 적용되는 상황을 의미
- 반복적으로 일어날 수 있는 상황
- 문제(Problem)
- 컨텍스트 내에서 이뤄야 하는 목표
- 컨텍스트 내의 제약조건도 포함
- 해결책(Solution)
- 찾아내야 하는 것
- 제약조건 속에서 누가 적용해도 목표를 이룰 수 있는 일반적인 디자인을 뜻함
어떤 컨텍스트 내에서 일련의 제약조건에 의해 영향을 받는 문제가 발생했다면, 그 제약조건 내에서 목적 달성을 위한 해결책이 되는 디자인을 적용한다.
- 패턴은 반복적으로 등장하는 문제에 적용할 수 있어야 한다.
- 반복적으로 적용할 수 있는 해결책이 아니라면 패턴이라고 할 수 없다.
- 해결책을 다른 사람에게 알려줘서 그 사람이 처함 문제의 해결책으로 적용할 수 있어야 한다.
디자인 패턴은 일상적이고 반복적으로 등장하는 디자인 문제의 해결책이다. 패턴을 정의할 수 있어야 다양한 장점을 제공하는 패턴 카탈로그를 만들 수 있다.
패턴 카탈로그
소프트웨어 디자인에서 자주 발생하는 문제들에 대한 해결책을 제시하는 인련의 디자인 패턴을 모아둔 문서 또는 자료이다.
디자인 패턴 카탈로그는 다양한 디자인 패턴을 설명하고 각 패턴의 사용 시나리오, 구현 방법, 이점 등을 자세히 설명하여 개발자들이 필요할 때 참고할 수 있도록 도와준다.
- 이름
- 패턴에서 중요한 요소로 제대로 된 이름이 없다면 패턴의 정보를 다른 개발자들과 공유하기 힘들어진다.
- 패턴의 종류 또는 범주
- 용도(Intent)
- 패턴의 역할을 간단하게 기술
- 패턴을 정의할 때 썻던 내용들이 들어가게됨
- 동기(Motivation)
- 문제를 기술하고 주어진 해결책이 어떤 시긍로 그 문제를 해결하는지 보여주는 구체적인 시나리오
- 적용 대성(Applicability)
- 패턴을 적용할 수 있는 상황을 기술
- 구조(Structure)
- 패턴에서 쓰이는 클래스들의 관계를 보여주는 다이어그램 수록
- 구성 요소(Participant)
- 클래스와 객체들의 설명
- 패턴 내에서 각 클래스(객체)가 맡는 임무와 역할을 설명
- 협동(Collaborations)
- 각 구성 요소가 패턴 내에서 어떤 식으로 서로 도움을 주는지 설명
- 결과(Consequences)
- 이 패턴을 사용했을 때의 효과(장점 및 단점) 수록
- 구현(Implementation)
- 패턴을 구현할 때 필요한 기술과 주의사항
- 샘플 코드(Sample Code)
- 구현하는 데 도움이 될만한 코드
- 사용 예(Known uses)
- 실제 시스템에서 이 패턴을 사용하는 예시 설명
- 연관 패턴(Related Patterns)
- 해당 패턴과 다른 패턴 사이의 관계를 설명하는 내용
새로운 디자인 패턴 발견하기
패턴은 만들어지는 것이 아니라 발견되는 것이다.
특화된 분야에서 일을 하다 보면 유용한 패턴을 새로 발견하는 경우도 있고, 자주 발생하는 문제의 일반적인 해결책을 찾아내는 경우도 있다.
- 기존 패턴을 확실하게 파악한다.
- 새로워 보이는 패턴도 기존 패턴을 변형한 경우가 많다.
- 패턴을 알아보는 눈이 길러지고 다른 패턴과 연관 짓는 능력도 발달한다.
- 패턴에 관한 아이디어는 경험(문제와 사용했던 해결책)에서 나온다.
- 지금까지의 경험을 토대로 곰곰히 생각해 보고, 반복적으로 발생하는 문제를 해결할 수 있는 새로운 디자인이 되도록 다듬는다.
- 문서화 해본다.
- 다른 사람들이 직접 적용해 보고 피드백을 제공할 수 있도록 문서로 만든다.
- 새로운 패턴을 사람들이 사용하게 해서 계속 다듬는다.
- 패턴을 한 번에 완성하긴 어려우므로, 패턴을 시험해 볼 기회를 제공하고 피드백을 얻는다.
- 3의 규칙
- 패턴이 실전 문제 해결에 3번 이상 적용되어야 패턴 자격을 얻을 수 있다.
디자인 패턴 분류하기
점점 더 많은 디자인 패턴이 발견됨에 따라 디자인 패턴을 찾거나 같은 그룹에 속하는 패턴끼리 비교하기 좋게 분류할 필요성이 생겼다.
대부분 카탈로그에서는 몇 가지 범주에 맞춰 디자인 패턴을 분류하고 있으며, 제일 유명한 분류 방법은 용도에 따라 나누는 방법이다.
- 생성 패턴(Creational Pattern)
- 객체 인스턴스를 생성하는 패턴으로, 클라이언트와 그 클라이언트가 생성해야 하는 객체 인스턴스 사이의 연결을 끊어주는 패턴
- 행동 패턴(Behavioral Pattern)
- 클래스와 객체들이 상호작용하는 방법과 역할을 분담하는 방법을 다루는 패턴
- 구조 패턴(Structural Pattern)
- 클래스와 객체를 더 큰 구조로 만들 수 있게 구성을 사용하는 패턴
그 외에도 클래스 또는 객체를 다루는 패턴이라던가 하위 범주를 다시 나누는 등 여러 방식으로 분류하고 있다.
패턴으로 생각하기
패턴으로 생각한다는 것은 어떤 디자인을 봤을 때 패턴 적용 여부를 결정할 수 있는 안목을 가진다는 의미이다.
최대한 단순하게
디자인을 할 때 가장 중요한 원칙은 **최대한 단순한 방법(KISS, Keep it Simple)**으로 문제를 해결하기다.
- “문제에 어떤 패턴을 적용할 수 있을까?” 라는 접근이 아닌 “어떻게 하면 단순하게 해결할 수 있을까?“에 초점을 맞춘다.
패턴 없이도 정말 단순하고 잘 만들 수 있다면 적용하면 되고, 가장 단순하고 유연한 디자인을 만들 때 패턴이 필요하다면 그때 적용한다.
디자인 패턴은 만병 통치약이 아니다.
패턴은 반복적으로 발생하는 문제의 일반적인 해결책이므로, 패턴을 사용할 때 설계한 디자인에 미칠 영향과 결과를 주의 깊게 생각해봐야한다.
패턴이 필요할 때
현재 디자인상의 문제에 적합다는 확신이 드는 경우 패턴을 도입해야한다.
- 더 간단한 해결책이 있다면 패턴을 적용하기 전 그 해결책 사용을 고려한다.
- 간단한 해결책만으로는 부족하다고 확신을 가지면 해결해야 할 문제와 제약 조건을 종합적으로 고려하여 적합한 패턴을 적용한다.
- 간단한 해결책으로 문제가 해결되는 데도 시스템의 어떤 부분이 변경될 것이라 예측되는 상황에는 디자인 패턴을 적용한다.
리펙터링과 패턴
패턴을 통해 구조가 개선될 수 있을지 검토해 볼 수 있다.
디자인 패턴 제거
패턴보다 간단한 해결책이 더 나을 것 같다면 패턴을 제거한다.
- 시스템이 복잡해지며 기대했던 유연성이 발휘되지 못하는 경우 등
꼭 필요하지 않은 패턴을 미리 적용하지 않는다.
지금 당장 변화에 대처하는 디자인을 만꼭 필요하지 않는 데도 패턴을 추가하면 시스템만 복잡해지고, 나중에 그 패턴을 사용하지 않을 수도 있다.
안티 패턴
안티 패턴(Anti-Pattern)은 어떤 문제의 나쁜 해결책에 이르는 길을 알려준다.
- 나쁜 해결책에 유혹되는지 알려준다.
- 나쁜 해결책이 어떤 식으로 사람들을 꼬시는지 설명함으로써 쓰지 않도록 경고한다.
- 장기적인 관점에서 나쁜 이유를 알려준다.
- 어떠한 부정적인 효과와 문제가 발생하는지 알린다.
- 좋은 해결책을 만들 때 적용할 수 있는 다른 패턴을 제안해준다.
구성
- 이름
- 문제
- 컨텍스트
- 원인
- 잘못된 해결책
- 바람직한 해결책
- 예시
핵심 정리
- 디자인 패턴은 자연스럽게 적용한다.
- 억지로 적용하면 안된다.
- 디자인 패턴은 돌에 새겨진 글씨가 아니므로 필요에 따라 적당히 변형한다.
- 주어진 조건을 만족하는 가잔 간단한 해결책을 사용한다.
- 디자인 패턴을 무조건 쓸 필요는 없다.
- 디자인 패턴 카탈로그를 읽어 보고 패턴을 숙지한다.
- 패턴 사이의 관계도 확실히 이해해야 한다.
- 패턴을 분류해서 패턴 그룹을 만들 수 있다.
- 그룹으로 나누는 것이 패턴 이해에 도움이 된다면 적극적으로 나눠본다.
- 패턴 작가가 되려면 대단한 노력이 필요하다.
- 오랜 시간 동안 패턴을 다음어야 한다.
- 이후 접할 패턴은 대부분 기존 패턴을 응용한 것이다.
- 주변 사람들과 전문 용어를 공유하자.
- 공통의 언어로 얘기할 수 있다는 점이 패턴의 가장 큰 장점이다.