13. 패턴과 함께 하는 행복한 삶

  1. 13. 패턴과 함께 하는 행복한 삶
    1. 디자인 패턴의 정의
    2. 디자인 패턴의 정의를 조금 더 자세히 살펴 봅시다.
    3. 디자인 패턴 작가가 되고 싶으신가요?
    4. 각 패턴을 올바르게 설명한 내용을 찾아 주세요
    5. 디자인 패턴 분류하기
    6. 패턴으로 생각하기
    7. 패턴을 대하는 마음가짐
    8. 전문 용어의 위력을 잊지 맙시다
    9. 패턴을 찾아 떠나는 여행
    10. 패턴 동물원
    11. 사악한 안티 패턴 섬멸하기
    12. 문서에 대하여

디자인 패턴의 정의

패턴 이란 특정 컨텍스트 내에서 주어진 문제 에 대한 해결책 이다.

정의가 조금 애매하죠?

  • 컨텍스트(context)란 패턴이 적용되는 상황을 뜻합니다. 반복적으로 일어 날 수 있는 상황이어야만 합니다.
  • 문제(problem)란 컨텍스트 내에서 이루고자 하는 목적을 뜻합니다. 또한 컨텍스트 내에서 생길 수 있는 제약조건도 문제에 포함됩니다.
  • 해결책(solution)이 바로 우리가 찾아내야 하는 것입니다.
    누구든지 적용해서 일련의 제약조건 내에서 목적을 달성할 수 있는 일반적인 디자인을 뜻합니다.

사실 디자인 패턴이라는 것은 일상적으로, 반복적으로 등장하는 디자인 문제에 대한 해결책 이라는 것을 이미 알고 있다.
근데 왜 이렇게 정형적인 정의를 따져야 하는 걸까? 패턴을 정형적으로 기술해 놓아야 패턴 카탈로그를 만들 수 있기 때문이다.

디자인 패턴의 정의를 조금 더 자세히 살펴 봅시다.

  • 문제 : 어떻게 회사에 제 시간에 도착할 것인가?
  • 컨텍스트 : 열쇠를 차에 두고 문을 잠그고 나와 버렸다.
  • 해결책 : 유리를 깬다. 차에 들어간다. 시동을 걸고 차를 몰고 출근한다.

디자인패턴의 정의에 따라 문제, 컨텍스트, 그리고 (실제로 통할 수 있는) 해결책을 정의했습니다.
이것을 패턴이라고 할 수 있을까요? 패턴이라고 할 수 없다면 그 이유는 뭇었일까요?
객체지향 디자인 패턴을 정의할 때도 이런 일이 생길 수 있을까요?

위 예저는 실제로 패턴이라고 할 수 없다. 그 이유는 무엇일까?

  • 우선 가장 먼저 생각할 수 있는 이유로 패턴은 반복적으로 등장하는 문제에 적용될 수 있어야 하기 때문이다.
  • 또 다른 이유는 이런 해결책을 다른 사람한테 알려주고 그 사람이 처한 문제에 대한 해결책으로 적용하게 하기가 힘들다는 점이다.
  • 세 번재 이유는 간단하면서도 중요한 패턴의 특징을 위배했다는 것이다. 패턴에 이름을 붙이지 않았다는 거죠
    이름이 없다면 다른 개발자들하고 그 패턴에 대해서 토론하는 것이 거의 불가능할 것이다.

다행이도 패턴은 문제, 컨텍스트, 해결책만 가지고 기술되거나 문서화 되지 않는다.
패턴을 기술하고 패턴 카탈로그에 수록할 때 사용할 수 있는 훨씬 훌륭한 방법이 있다.

패턴카탈로그

  • 패턴카탈로그에는 패턴의 용도와 패턴이 만들어지게 된 배경, 적용될 수 있는 범위, 해결책의 디자인 및
    그 해결책을 적용한 결과(장단점)와 같이 훨씬 다양한 내용이 자세히 기술된다.
  • 가장 훌륭한 패턴카탈로그로는 (GOF의 디자인패턴:Design Patterns)를 들 수 있다.

패턴 카탈로그의 기술형식(Page 623)

  • 패턴 종류 또는 범주
  • 패턴 이름
    • 패턴 설명에서 가장 먼저 등장, 패턴의 이름 없이는 패턴에 대한 정보를 다른 개발자들과 공유하기가 아주 힘들어 진다.
  • 용도(Intent)
    • 패턴의 역할이 간단히 기술된다.
  • 동기(Motivation)
    • 문제를 기술하고 주어진 해결책이 어떤 식으로 그 문제를 해결 할 수 있는지를 보여줄 수 있는 구체적인 시나리오가 주어진다.
  • 적용대상(Applicability)
    • 패턴을 적용할 수 있는 상황이 기술된다.
  • 구조(Structure)
    • 패턴에서 사용되는 클래스 다이어그램이 수록된다.
  • 구성요소(Participant)
    • 디자인패턴에 포함되어 있는 클래스와 객체들에 대한 설명
  • 협동(Collaboration)
    • 각 구성요소들이 패턴 내에서 어떤 식으로 도움을 주는지 설명.
  • 결과(Consequence)
    • 패턴을 사용했을 때의 효과(장점 및 단점)가 수록됨
  • 구현(Implementation)
    • 패턴을 구현할 때 필요한 기술 및 주의사항에 대해 설명
  • 샘플코드(Sample Code)
    • 구현시 도움 될 만한 코드 제공
  • 사용예(Known Uses)
    • 실제 시스템에서 이 패턴을 사용하는 예에 대한 설명
  • 관련패턴 (Related Patterns)
    • 본 패턴과 유사하거나 밀접하게 관련된 다른 패턴에 대해서 기술

디자인 패턴 작가가 되고 싶으신가요?

우선 패턴은 만들어지는 것이 아니라 발견되는 것이라는 점을 꼭 기억해 두세요
디자인 패턴은 누구든지 발견할 수 있고, 자기가 발견한 디자인 패턴에 대해서 제대로 설명할 수만 있으면 됩니다.

  • 숙제 먼저 합시다.
    • 새로운 패턴을 만들기 전에 기존 패턴을 확실하게 파악하고 있어야 합니다.
    • 새로운 패턴도 기존 패턴을 변형시킨 것이 대부분이다.
  • 오랜 시간에 걸쳐서 심사숙고해 보세요
    • 패턴에 대한 아이디어는 경험(접해본 문제와 해결책)에서 나온다.
  • 머리속에 들어있는 아이디어를 남들도 이해할 수 있도록 종이 위에 적는다.
    • 새로운 패턴을 발견했다면, 다른 사람들이 직접 적용할 수 있도록 GoF 템플릿 형식으로 문서화 한다.
  • 다른 사람들이 새 패턴을 사용하게 해 보고, 계속해서 다듬는다.
    • 다른 개발자에게 검증 받는 과정을 거쳐 훌륭한 패턴으로 발전 할 수 있다.
  • 3의 규칙(Rule of Three)을 잊지 마세요
    • 실전문제에서 세 번 이상 적용되지 않은 이상 패턴 자격이 없다는 것을 잊지 말아라.

각 패턴을 올바르게 설명한 내용을 찾아 주세요

{html}
<pre>
1. 데코레이터 패턴 <font color="#FFFFFF">(10)</font> 1. 객체를 감싸서 다른 인터페이스를 제공합니다.
2. 스테이트 패턴 <font color="#FFFFFF">(7)</font> 2. 알고리즘의 개별 단계를 구현하는 방법을 서브클레스에서 결정 합니다.
3. 이터레이터 패턴 <font color="#FFFFFF">(8)</font> 3. 생성할 구상 클래스를 서브클래스에서 결정 합니다.
4. 퍼사드 패턴 <font color="#FFFFFF">(9)</font> 4. 딱 한 객체만 생성되도록 합니다.
5. 스트래티지 패턴 <font color="#FFFFFF">(5)</font> 5. 교환 가능한 행동을 캡슐화하고 위임을 통해서 어떤 행동을 사용할지 결정합니다.
6. 프록시 패턴 <font color="#FFFFFF">(13)</font> 6. 클라이언트에서 객체 컬렉션과 개별 객체를 똑같이 다룰 수 있도록 해 줍니다.
7. 팩토리 메소드 패턴 <font color="#FFFFFF">(3)</font> 7. 상태를 기반으로 한 행동을 캡슐화 한 다음 위임을 통해서 필요한 행동을 선택합니다.
8. 어댑터 패턴 <font color="#FFFFFF">(1)</font> 8. 컬렉션이 어떤 식으로 구현되었는지 드러내진 않으면서도 컬렉션 내에 있는 모든 객체에
대해 반복작업을 처리할 수 있게 해줍니다.
9. 옵저버 패턴 <font color="#FFFFFF">(12)</font> 9. 일련의 클래스에 대해서 간단한 인터페이스를 제공합니다.
10.템플릿 메소드 패턴 <font color="#FFFFFF">(2)</font> 10. 객체를 감싸서 새로운 행동을 제공합니다.
11.컴포지트 패턴 <font color="#FFFFFF">(6)</font> 11. 클라이언트에서 구상클래스를 지정하지 않으면서도 일군의 객체를 생성할 수 있도록 해 줍니다.
12.싱글턴패턴 <font color="#FFFFFF">(4)</font> 12. 상태가 변경되면 다른 객체들한테 연락을 돌릴 수 있게 해 줍니다.
13.추상 팩토리 패턴 <font color="#FFFFFF">(11)</font> 13. 객체를 감싸서 그 객체에 대한 접근을 제어합니다.
14.커맨드 패턴 <font color="#FFFFFF">(14)</font> 14. 요청을 객체로 감쌉니다.
</pre>
{html}

디자인 패턴 분류하기

대부분의 카탈로그에서는 몇 가지 범주에 맞쳐서 디자인 패턴을 분류하고 있습니다.
가장 대표적인 분류 방법은 용도에 따라서 생성,행동, 구조라는 세가지 범주로 나느는 방법 입니다.

용도에 따른 분류

  • 생성 관련 패턴 (Creational Pattern)
    • 객체 인스턴스 생성을 위한 패턴
    • 싱글턴, 빌더, 프로토타입, 추상 팩토리, 팩토리 메소드
  • 행동 관련 패턴 (Behavioral Pattern)
    • 클래스와 객체들이 상호 작용하는 방법 및 역할을 분담하는 방법과 관련된 패턴
    • 템플릿메소드, 이터레이터, 커맨드, 스테이트, 스트레티지, 인터프리터, 비지터, 메멘토
  • 구조 관련 패턴 (Structural Pattern)
    • 클래스및 객체들을 구성을 통해서 더 큰 구조로 만들 수 있게 해 주는 것과 관련된 패턴
    • 데코레이터, 컴포지트, 프록시, 퍼사드, 어댑터, 브리지, 플라이웨이트

클래스와 객체에 따른 분류

  • 클래스 패턴(Class Pattern)
    • 클래스 사이의 관계가 상속을 통해서 어떤 식으로 정의되는지를 다룹니다.
    • 클래스 패턴에서는 컴파일시에 관계가 결정 됩니다.
    • 템플릿 메소드, 어댑터, 팩토리 메소드, 인터프리터
  • 객체 패턴(Object Pattern)
    • 객체 사이의 관계를 다루며, 객체 사이의 관계는 보통 구성을 통해서 정의 됩니다.
    • 객체 패턴에서는 일반적으로 실행 중에 관계가 생성되기 때문에 더 동적이고 유연합니다.
    • 검포지트, 데코레이터, 프록시, 스트레티지, 추상 팩토리, 퍼사드, 커맨드, 옵져버, 스테이트, 싱글턴

패턴으로 생각하기

  • 최대한 단순하게(KISS-Keep it Simple)
    • 가장 중요한건 최대한 단순한 방법으로 문제를 해결해야 한다는 점이다.
    • 어떻게 패턴을 적용 할 수 있는가? 보다는 어떻게 하면 단순하게 해결할 수 있을까에 초점을 맞춰야 한다.
  • 디자인패턴은 만병 통치약이 아니다.
    • 패턴은 반복적으로 발생하는 문제에 대한 일반적인 해결책이고, 수 많은 개발자들에 의해서 오랫동안 검증받은 해결책이다.
    • 하지만 패턴을 사용 했을 때 설계한 디자인의 다른 부분에 미칠 수 있는 영향과 결과에 대해 주의 깊게 생각해 봐야 한다.
  • 다음과 같은 경우에 패턴이 필요하다.
    • 디자인을 할 때, 지금 디자인상의 문제에 적합하다는 확신이 들 경우에 패턴을 도입해야 한다.
    • 만약 더 간단한 해결책이 있다면 패턴을 적용하기 전에 그 해결책을 사용하는 것을 고려해야 한다.
    • 패턴을 도입하는 것은 디자인 단계에서만 고려해야 하는 일이 아니라, 리팩토링 할 때도 패턴을 고려해야 한다.
  • 리팩토링과 패턴
    • 리팩토링(refactoring)이란 코드 구조를 개선하기 위해서 코드를 변경하는 과정을 말한다.
    • 리팩토링의 목적은 행동을 변경하는 것이 아니라 구조를 개선하는 데 있다.
    • 패턴을 이용하면 구조를 좀 더 효율적으로 개선 할 수 있다.
  • 꼭 필요하지 않은 것은 빼 버립시다.
    • 상황에 따라서는 디자인 패턴을 제거하는 것에 대해서 생각해 봐야 한다.
    • 시스템이 점점 복잡해 지면서 처음에 기대했던 유연성이 전혀 발휘되지 않는 경우 패턴을 과감히 제거하는 것이 낫다.
  • 꼭 필요하지 않은 것을 미리 할 필요는 없다.
    • 꼭 필요하지 않음에도 불구하고 괜히 패턴을 추가하는 것은 피해야 한다.

패턴을 대하는 마음가짐

  • 초보자
    • "Hello World 프로그램에도 패턴을 써 봐야지.."
    • 초보자들은 언제나 패턴을 사용하는 경향이 있다. 바람직한 일이다.
      그 과정에서 다양한 경험을 쌓고, 그러다 보면 어떤 디자인이든 단순하게 만들어야 한다는 것을 터득하게 된다.
  • 중급자
    • "여기에는 싱글턴을 쓰는 게 좋겠어"
    • 어떤 상항에서 패턴이 필요하고, 어떤 상황에서 패턴이 필요하지 않은지 알 수 있다.
  • 달인
    • "이 부분에는 데코레이터가 들어갈 수 밖에 없겠군."
    • 더 이상 패턴을 사용하는 것에 얽매이지 않고, 문제를 가장 효과적으로 해결할 수 있는 해결책을 찾는데 주안점을 둔다.

경고

디자인 패턴의 과다한 사용은 불필요하게 복잡한 코드를 초래 할 수 있습니다.
항상 가장 간단한 해결책으로 목적을 달성할 수 있도록 하고, 반드시 필요할 때만 디자인 패턴을 적용합시다.

전문 용어의 위력을 잊지 맙시다

  • 디자인 패턴은 문제를 해결하기 위해서 존재하지만, 개발자들 사이에서 의사 소통을 하는데 필요한 용어를 제공하기도 한다.
  • 즉 디자인 패턴은 의사 소통에 있어서 큰 도움이 된다.

패턴을 찾아 떠나는 여행

패턴 동물원

  • 건축 패턴(Architectural Patterns)
    • 생동감 있는 건물,마을,도시를 만들기 위한 용도로 사용된다.
    • 패턴이라는 개념이 여기서 처음 만들어 졌다.
  • 애플리케이션 패턴(Application Patterns)
    • 시스템 수준의 아키텍처를 만들기 위한 패턴이다.
    • 3-Tier 아키텍처, 클라이언트 시스템, 웹, SOA
  • 특정 영역용 패턴(Domain-Specific Patterns)
    • 특정 영역에 국한된 문제와 관련된 패턴
    • J2EE
  • 비즈니스 프로세스 패턴(Business Proces Patterns)
  • 조직 패턴(Organizational Patterns)
  • 사용자 인터페이스 디자인 패턴(User Interface Design Patterns)

사악한 안티 패턴 섬멸하기

  • 안티 패턴이란 어떤 문제에 대해서 나쁜 해결책에 이르는 길이다.
  • 안티 패턴의 요소
    • 안티 패턴은 어떤 이유로 나쁜 해결책에 유혹될 수 있는지를 알려 준다.
    • 안티 패턴은 장기적인 관점에서 그 해결책이 나쁜 이유를 알려준다.
    • 안티 패턴에서는 좋은 해결책을 만들어 내기 위해 적용할 수 있는 다른 패턴을 제안해 준다.
    • http://c2.com/ 에서 다양한 안티패턴을 찾아 볼 수 있다.

문서에 대하여