맨위로가기

디자인 패턴 (책)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

'디자인 패턴'은 에리히 감마, 리처드 헬름, 랄프 존슨, 존 블리시데스가 쓴 객체 지향 설계 패턴에 관한 책이다. 이 책은 1994년 OOPSLA 회의에서 처음 공개되었고, 1995년에 출판되었다. 책은 객체 지향 설계 원칙, 생성, 구조, 행동 패턴의 분류를 제시하며, 어댑터, 브리지, 컴포지트, 데코레이터, 파사드, 플라이웨이트, 프록시, 책임 연쇄, 커맨드, 인터프리터, 이터레이터, 중재자, 메멘토, 옵저버, 상태, 전략, 템플릿 메서드, 방문자 패턴 등을 설명한다. 이 책은 소프트웨어 디자인 패턴의 개념에 대한 비판과, C++의 기능 부족을 해결하기 위한 방법이라는 비판을 받기도 했다.

더 읽어볼만한 페이지

  • 소프트웨어 공학 책 - 성당과 시장
    성당과 시장은 에릭 S. 레이먼드가 자유 소프트웨어 개발 모델을 성당 모델과 바자 모델로 나누어 설명한 에세이로, 바자 모델의 우수성을 주장하며 오픈 소스 개발에 대한 교훈을 제시하고 넷스케이프와 위키백과에 영향을 미쳤으나 비판도 존재한다.
  • 1994년 책 - 세계의 어류
  • 1994년 책 - 나의 문화유산답사기
    유홍준이 집필한 《나의 문화유산답사기》는 한국 각 지역의 문화유산의 역사적 배경, 예술적 가치, 흥미로운 이야기들을 담아 한국의 역사와 문화를 깊이 있게 이해하고 감상할 수 있도록 돕는 인문학적 지침서로 평가받는 문화유산 답사기이다.
  • 소프트웨어 디자인 패턴 - 모델-뷰-컨트롤러
    모델-뷰-컨트롤러(MVC)는 소프트웨어 디자인 패턴으로, 응용 프로그램을 모델, 뷰, 컨트롤러 세 가지 요소로 분리하여 개발하며, 사용자 인터페이스 개발에서 데이터, 표현 방식, 사용자 입력 처리를 분리해 유지보수성과 확장성을 높이는 데 기여한다.
  • 소프트웨어 디자인 패턴 - 스케줄링 (컴퓨팅)
    스케줄링은 운영 체제가 시스템의 목적과 환경에 맞춰 작업을 관리하는 기법으로, 장기, 중기, 단기 스케줄러를 통해 프로세스를 선택하며, CPU 사용률, 처리량 등을 기준으로 평가하고, FCFS, SJF, RR 등의 알고리즘을 사용한다.
디자인 패턴 (책) - [서적]에 관한 문서
책 정보
제목디자인 패턴: 재사용 가능한 객체 지향 소프트웨어의 요소
원제Design Patterns: Elements of Reusable Object-Oriented Software
저자에리히 감마
리처드 헬름
랄프 존슨
존 블리시디스
국가미국
주제디자인 패턴
소프트웨어 공학
객체 지향 프로그래밍
출판사애디슨-웨슬리
출판일1994년
페이지 수395쪽
ISBN0-201-63361-2
OCLC31171684
Dewey 십진분류법005.1/2 20
의회 도서관 번호QA76.64 .D47 1995

2. 역사

이 책의 집필은 1990년 OOPSLA 컨퍼런스에서 시작되어 1994년에 출판되었다.[6]

2. 1. 개발 배경

이 책의 시작은 1990년 OOPSLA 회의에서 "아키텍처 핸드북을 향하여"라는 주제로 열린 동아리 모임이었다. 이 모임에서 에리히 감마(Erich Gamma)와 리처드 헬름(Richard Helm)이 만나 공통의 관심사를 발견했고, 이후 랄프 존슨(Ralph Johnson)과 존 블리시데스(John Vlissides)가 합류했다.[6] 책은 1994년 10월 21일에 처음 출판되었으며(저작권은 1995년), 같은 해 OOPSLA 회의에서 일반에 공개되었다.

2. 2. 출판 및 영향

이 책의 집필은 1990년 OOPSLA 컨퍼런스에서 열린 "아키텍처 핸드북을 향하여"라는 주제의 동아리 모임에서 시작되었다. 이 모임에서 에리히 감마와 리처드 헬름이 만나 공통 관심사를 확인했고, 이후 랄프 존슨과 존 블리시데스가 합류했다.[6] 책은 1994년 10월 21일에 처음 출판되었으며(저작권은 1995년), 같은 해 OOPSLA 컨퍼런스에서 대중에게 공개되었다.

2005년, ACM SIGPLAN은 이 책의 저자들에게 프로그래밍 언어 업적상을 수여하며, 그들의 작업이 "프로그래밍 실무와 프로그래밍 언어 설계"에 미친 영향을 인정했다.[7]

그러나 소프트웨어 디자인 패턴 개념 전반, 특히 이 책에 대한 비판도 제기되었다. 주요 비판 중 하나는 책에서 소개된 패턴들이 C++ 언어의 부족한 기능을 보완하기 위한 임시방편에 불과하며, 간결한 추상화 대신 길고 구체적인 패턴을 사용하게 만들어 프로그래머를 사실상 "인간 컴파일러"로 만든다는 것이다. 폴 그레이엄은 다음과 같이 지적했다.[8]

: 내 프로그램에서 패턴을 발견하면 문제의 징조로 여깁니다. 프로그램의 형태는 해결해야 할 문제만을 반영해야 합니다. 코드에서 다른 규칙성은 적어도 제가 보기에, 제가 충분히 강력하지 않은 추상화를 사용하고 있다는 신호입니다. 종종 손으로 작성해야 하는 매크로의 확장을 생성하고 있습니다.

피터 노빅은 책에 소개된 23개 패턴 중 16개가 Lisp나 Dylan과 같은 동적 프로그래밍 언어의 기능을 사용하면 더 단순해지거나 아예 필요 없어진다는 것을 보여주었다.[9] 한네만(Hannemann)과 키찰레스 역시 비슷한 관찰 결과를 발표했다. 그들은 관점 지향 프로그래밍 언어인 AspectJ를 사용하여 23개 디자인 패턴 중 다수를 구현했고, 그 결과 17개 패턴 구현에서 코드 수준의 종속성이 제거되었음을 확인했다. 이는 관점 지향 프로그래밍이 디자인 패턴 구현을 단순화할 수 있음을 시사한다.[10]

2009년 InformIT과의 인터뷰에서 에리히 감마는 2005년에 저자들이 모여 책을 어떻게 개선할지 논의했다고 밝혔다. 논의 결과, 일부 패턴을 재분류하고 확장 객체/인터페이스, 의존성 주입, 유형 객체, 널 객체 등 몇 가지 패턴을 추가하는 방향으로 의견이 모였다. 감마는 개인적으로 싱글턴 패턴을 제거하고 싶었지만, 저자들 간의 완전한 합의에는 이르지 못했다고 덧붙였다.[11]

3. 객체 지향 설계 원칙

이 책의 1장에서는 저자들이 경험을 통해 좋은 객체 지향 소프트웨어 설계를 이끌어낸다고 믿는 설계 원칙들을 논의한다. 핵심 원칙으로는 다음 두 가지가 제시된다.


  • "구현이 아닌 인터페이스에 맞춰 프로그래밍하라." (Gang of Four 1995:18)
  • 상속보다 합성: "'객체 합성'을 '클래스 상속'보다 선호하라." (Gang of Four 1995:20)


또한 객체 간의 관계를 구분하는데, 한 객체가 다른 객체를 '소유'하거나 '일부'인 관계(집계)와 단순히 다른 객체를 '알고 있는' 관계(지인, 때로는 '연관' 또는 '사용' 관계로 불림)를 구별한다. 지인 관계는 집계보다 약한 연결이며, 객체 간의 느슨한 결합을 시사하여 설계의 유지보수성을 높이는 데 도움이 될 수 있다.

저자들은 '툴킷'과 '소프트웨어 프레임워크'라는 용어를 구분하여 사용한다. 그들의 용어에 따르면, 툴킷은 오늘날의 클래스 라이브러리와 유사한 재사용 가능한 코드 모음이며, 프레임워크는 특정 종류의 소프트웨어를 만들기 위한 재사용 가능한 설계를 구성하는 협력하는 클래스들의 집합이다. 저자들은 애플리케이션 설계도 어렵지만, 툴킷 설계는 더 어렵고, 프레임워크 설계가 가장 어렵다고 언급한다.

3. 1. 인터페이스를 통한 프로그래밍

이 책의 1장에서는 좋은 객체 지향 설계를 위한 원칙들을 제시한다. 그중 핵심적인 두 가지 원칙은 다음과 같다.

  • "구현이 아닌 인터페이스에 맞춰 프로그래밍하라." (Gang of Four 1995:18)
  • 상속보다 합성: "'객체 구성'을 '클래스 상속'보다 선호하라." (Gang of Four 1995:20)


저자들은 구현 대신 인터페이스를 사용하면 다음과 같은 장점이 있다고 주장한다.

  • 클라이언트는 객체가 특정 인터페이스를 만족하기만 한다면, 그 객체의 구체적인 타입이나 구현 클래스를 알 필요가 없다. 클라이언트는 오직 인터페이스를 정의하는 추상 클래스(들)만 알면 된다.


인터페이스를 사용하면 객체 지향 프로그래밍의 핵심 특징인 동적 디스패치다형성을 활용할 수 있게 된다.

저자들은 상속을 ''화이트 박스 재사용''이라고 부른다. 이는 상속을 통해 부모 클래스의 내부 구현이 하위 클래스에게 노출되는 경우가 많기 때문이다. 반면, 객체 구성은 ''블랙 박스 재사용''이라고 부른다. 객체 구성은 잘 정의된 인터페이스를 통해 다른 객체에 대한 참조를 얻어 런타임에 동적으로 사용하는 방식이다. 이 경우, 사용하는 코드는 구성된 객체의 내부 구현을 알 필요가 없다.

상속은 캡슐화를 해칠 수 있다는 문제점이 지적된다. 저자들은 경험적으로 설계자들이 상속을 남용하는 경향이 있다고 말하며(Gang of Four 1995:20), 다음과 같은 위험을 경고한다.

: "상속은 하위 클래스를 부모 클래스의 구현 세부 사항에 노출시키기 때문에, '상속은 캡슐화를 깨뜨린다'라고 흔히 말한다." (Gang of Four 1995:19)

하위 클래스의 구현이 부모 클래스의 구현에 너무 의존하게 되면, 부모 클래스의 구현이 변경될 때 하위 클래스도 함께 변경해야 하는 문제가 발생할 수 있다. 이를 피하기 위해 추상 클래스에서만 상속하는 방법이 있지만, 이는 코드 재사용을 최소화시킨다는 단점이 있다.

그럼에도 불구하고, 상속은 기존 컴포넌트의 기능을 확장하고, 기존 코드의 상당 부분을 재사용하며, 비교적 적은 양의 새 코드를 추가할 때 유용하게 사용될 수 있다.

저자들은 '위임'을 객체 구성의 극단적인 형태로 보며, 상속을 대체할 수 있는 방법으로 제시한다. 위임 관계에서는 '송신자' 객체가 '대리자' 객체에게 자신(this)을 전달하여, 대리자가 송신자를 참조할 수 있도록 한다. 이를 통해 두 객체 간의 연결이 컴파일 시점이 아닌 런타임에 동적으로 설정된다. 위임에 대한 더 자세한 내용은 콜백 문서에서 찾아볼 수 있다.

또한, 저자들은 제네릭(에이다, 에펠, Java, C#, Visual Basic (.NET), 델파이) 또는 템플릿(C++)으로 알려진 매개변수화된 타입에 대해서도 논의한다. 이 기능들은 특정 타입을 명시하지 않고도 범용적인 코드를 작성할 수 있게 해준다. 실제 사용 시점에 필요한 타입을 '매개변수'로 전달하여 구체화한다.

저자들은 위임과 매개변수화가 매우 강력한 기능임을 인정하면서도 다음과 같이 주의를 준다.

: "동적이고 고도로 매개변수화된 소프트웨어는 더 정적인 소프트웨어보다 이해하고 구축하기가 더 어렵다." (Gang of Four 1995:21)

객체 간의 관계에 대해서도 설명하는데, 한 객체가 다른 객체를 '소유'하거나 '부분'으로 갖는 관계(집계, aggregation)와 단순히 다른 객체를 '알고 있는' 관계(지인, 연관, 사용)를 구분한다. 집계는 두 객체의 생명주기가 같다는 의미를 내포하는 반면, 지인 관계는 서로의 기능을 요청할 수는 있지만 서로에게 책임은 지지 않는 더 약한 관계이다. 지인 관계는 객체 간의 느슨한 결합을 가능하게 하여, 설계의 유지보수성을 높이는 데 도움이 될 수 있다.

마지막으로, 저자들은 '툴킷'과 '소프트웨어 프레임워크'라는 용어를 구분하여 사용한다. 저자들의 용어에 따르면, 툴킷은 오늘날의 클래스 라이브러리와 유사하게 재사용 가능한 코드의 모음이며, 프레임워크는 특정 종류의 소프트웨어를 만들기 위한 재사용 가능한 설계 자체를 의미하는 협력하는 클래스들의 집합이다. 저자들은 애플리케이션 설계도 어렵지만, 툴킷 설계는 더 어렵고, 프레임워크 설계가 가장 어렵다고 말한다.

3. 2. 상속보다 합성 선호

이 책의 저자들은 경험을 바탕으로 좋은 객체 지향 소프트웨어 설계를 이끌 것이라고 믿는 두 가지 중요한 원칙을 제시한다.

첫째는 "구현이 아닌 인터페이스에 맞춰 프로그래밍하라"는 것이다 (Gang of Four 1995:18). 인터페이스를 사용하면 다음과 같은 장점이 있다.

  • 클라이언트는 객체가 특정 인터페이스를 만족하는 한, 실제 사용 중인 객체의 구체적인 유형을 알 필요가 없다.
  • 클라이언트는 객체를 구현하는 구체적인 클래스를 몰라도 되며, 인터페이스를 정의하는 추상 클래스에 대해서만 알면 된다.


인터페이스를 활용하면 객체 지향 프로그래밍의 핵심 기능인 동적 디스패치다형성을 자연스럽게 구현할 수 있다.

둘째 원칙은 "객체 합성을 클래스 상속보다 선호하라"는 것이다 (Gang of Four 1995:20). 이는 상속보다 합성 원칙으로 잘 알려져 있다.

저자들은 상속화이트 박스 재사용이라고 부른다. 이는 부모 클래스의 내부 구현이 종종 하위 클래스에게 노출되기 때문이다. 반면, 객체 합성은 블랙 박스 재사용이라고 설명한다. 객체 합성은 잘 정의된 인터페이스를 통해 다른 객체에 대한 참조를 얻어 런타임에 사용하는 방식으로, 합성된 객체의 내부 구현을 알 필요가 없다.

상속은 캡슐화와 충돌할 수 있다는 문제점을 지적한다. 저자들은 경험상 설계자들이 상속을 과도하게 사용하는 경향이 있다고 말하며 (Gang of Four 1995:20), 다음과 같은 위험성을 경고한다.

> "상속은 하위 클래스를 부모의 구현 세부 사항에 노출시키기 때문에, '상속은 캡슐화를 깨뜨린다'라고 흔히 말한다." (Gang of Four 1995:19)

하위 클래스의 구현이 부모 클래스의 구현과 너무 밀접하게 연결되면, 부모 클래스의 구현이 변경될 때 하위 클래스도 함께 변경해야 하는 문제가 발생할 수 있다. 이를 피하기 위해 추상 클래스에서만 상속하는 방법도 있지만, 이는 코드 재사용성을 크게 떨어뜨린다.

따라서 상속은 기존 구성 요소의 기능을 확장하고 대부분의 코드를 재사용하면서 최소한의 새 코드만 추가하는 경우에 주로 사용하는 것이 좋다.

저자들은 상속의 대안으로 위임을 제시한다. 위임은 객체 합성의 한 형태로, 한 객체('송신자')가 다른 객체('대리자')에게 작업을 대신 처리하도록 요청하는 방식이다. 이때 송신자는 자신을 대리자에게 전달하여 대리자가 송신자를 참조할 수 있게 한다. 이를 통해 두 객체 간의 연결이 컴파일 시점이 아닌 런타임에 동적으로 설정된다. 콜백 메커니즘과 관련이 깊다.

또한, 제네릭(에이다, 에펠, Java, C#, Visual Basic (.NET), 델파이) 또는 템플릿(C++)으로 알려진 매개변수화된 타입에 대해서도 언급한다. 이는 타입을 매개변수로 받아 다양한 타입에 대해 동작하는 코드를 작성할 수 있게 해주는 강력한 기능이다.

하지만 저자들은 위임과 매개변수화가 매우 강력하지만, 동시에 다음과 같은 점을 주의해야 한다고 말한다.

> "동적이고 고도로 매개변수화된 소프트웨어는 더 정적인 소프트웨어보다 이해하고 구축하기가 더 어렵다." (Gang of Four 1995:21)

객체 간의 관계에 대해서도 설명하는데, 한 객체가 다른 객체를 '소유'하거나 '부분'으로 가지는 집계(Aggregation) 관계와 단순히 다른 객체를 '알고 있는' 지인(Acquaintance) 관계를 구분한다. 지인 관계는 '연관' 또는 '사용' 관계로 불리기도 하며, 집계보다 약한 연결이다. 이는 객체 간의 느슨한 결합을 가능하게 하여 유지보수성을 높이는 데 도움이 될 수 있다.

마지막으로, 저자들은 툴킷(Toolkit)과 소프트웨어 프레임워크(Framework)라는 용어를 구분하여 사용한다. 툴킷은 오늘날의 클래스 라이브러리와 유사하게 재사용 가능한 코드 모음이라면, 프레임워크는 특정 종류의 소프트웨어를 만들기 위한 재사용 가능한 설계 자체를 의미한다. 저자들은 애플리케이션 설계도 어렵지만, 툴킷 설계는 더 어렵고, 프레임워크 설계가 가장 어렵다고 말한다.

3. 3. 위임

저자들은 위임상속 대신 사용할 수 있는 객체 합성의 한 형태로 본다. 위임은 두 객체, 즉 '송신자'와 '대리자' 사이에서 이루어진다. 송신자는 대리자에게 자기 자신을 전달하여, 대리자가 송신자를 참조할 수 있게 한다. 이 방식은 컴파일 시점이 아니라 프로그램 실행 중(런타임)에 두 객체 간의 연결이 이루어지도록 한다. 위임에 대한 더 자세한 내용은 콜백 문서에서 찾아볼 수 있다.

3. 4. 매개변수화된 유형 (제네릭)

저자들은 제네릭 또는 템플릿이라고 불리는 매개변수화된 유형에 대해서도 논의한다. 이는 에이다, 에펠, Java, C#, Visual Basic (.NET), 델파이와 같은 언어의 제네릭 기능이나 C++의 템플릿 기능에 해당한다. 이 기능을 사용하면, 특정 데이터 유형을 미리 지정하지 않고도 코드를 작성할 수 있다. 대신, 코드를 사용할 때 필요한 데이터 유형을 '매개변수'처럼 전달하여 지정한다.

저자들은 위임과 매개변수화된 유형이 매우 강력한 기능임을 인정하면서도, 다음과 같은 주의점을 언급한다.

:"동적이고 고도로 매개변수화된 소프트웨어는 더 정적인 소프트웨어보다 이해하고 구축하기가 더 어렵다." (Gang of Four 1995:21)

4. 디자인 패턴의 분류

디자인 패턴은 문제 해결 방식과 목적에 따라 일반적으로 세 가지 주요 범주로 분류된다. 각 범주는 소프트웨어 공학에서 자주 발생하는 특정 유형의 설계 문제를 해결하는 데 중점을 둔다.


  • 생성 패턴 (Creational Patterns): 객체의 생성 과정을 다루는 패턴이다. 특정 상황에 어떤 객체를 생성해야 하는지에 대한 결정을 유연하게 처리하여, 코드의 의존성을 줄이고 객체 생성 로직을 캡슐화하는 데 도움을 준다.
  • 구조 패턴 (Structural Patterns): 클래스와 객체를 조합하여 더 큰 구조를 형성하는 방법을 다룬다. 상속이나 객체 합성을 통해 클래스나 객체 간의 관계를 효과적으로 구성하고, 새로운 기능을 유연하게 추가할 수 있도록 돕는다.
  • 행동 패턴 (Behavioral Patterns): 객체 간의 상호작용 방식과 책임 분담에 관한 패턴이다. 객체들이 효과적으로 협력하고 통신할 수 있도록 다양한 알고리즘과 책임 할당 방식을 제공하여 시스템의 유연성과 재사용성을 높인다.


각 분류에 속하는 구체적인 디자인 패턴과 그 상세한 설명은 이어지는 하위 섹션들에서 다룬다.

4. 1. 생성 패턴 (Creational Patterns)

생성 패턴은 객체를 직접 인스턴스화하는 대신 객체를 생성하는 패턴이다. 이는 특정 경우에 어떤 객체를 생성해야 하는지 결정하는 데 있어 프로그램에 더 많은 유연성을 제공한다. 생성 패턴에는 다음과 같은 종류가 있다.

4. 1. 1. 추상 팩토리 패턴 (Abstract Factory)

추상 팩토리 패턴은 동일한 주제나 공통 테마를 가진 다른 팩토리들을 그룹화하는 생성 패턴이다.

4. 1. 2. 빌더 패턴 (Builder)

빌더 패턴은 생성(constructioneng)과 표현(representationeng)을 분리하여 복잡한 객체를 생성하는 패턴이다.

4. 1. 3. 팩토리 메서드 패턴 (Factory Method)

팩토리 메서드 패턴은 생성할 객체의 정확한 클래스를 지정하지 않고 객체를 생성하는 패턴이다.

4. 1. 4. 프로토타입 패턴 (Prototype)

프로토타입 패턴은 기존 객체를 복제함으로써 객체를 생성하는 생성 패턴이다.

4. 1. 5. 싱글톤 패턴 (Singleton)

싱글턴 패턴은 한 클래스에 오직 하나의 객체만 존재하도록 제한하는 생성 패턴이다.

4. 2. 구조 패턴 (Structural Patterns)

구조 패턴은 클래스와 객체 구성을 다룬다. 이들은 인터페이스를 구성하고, 새로운 기능을 얻기 위해 객체를 구성하는 방법을 정의하기 위해 상속을 사용한다. 구조 패턴에는 다음과 같은 것들이 있다.

4. 2. 1. 어댑터 패턴 (Adapter)

어댑터 패턴은 호환되지 않는 인터페이스를 가진 클래스가 기존 클래스의 인터페이스를 래핑하여 함께 작동할 수 있도록 한다.

4. 2. 2. 브리지 패턴 (Bridge)

브리지 패턴추상화구현을 분리하여, 이 둘을 각각 독립적으로 발전시킬 수 있도록 하는 구조 패턴이다.[1][2]

4. 2. 3. 컴포지트 패턴 (Composite)

컴포지트 패턴은 0개 이상의 유사한 객체를 묶어 하나의 객체처럼 이용하거나 조작할 수 있게 한다.[1][2]

4. 2. 4. 데코레이터 패턴 (Decorator)

데코레이터 패턴은 객체의 기존 메서드에 새로운 행동을 동적으로 추가하거나 재정의할 수 있도록 한다.

4. 2. 5. 파사드 패턴 (Facade)

파사드 패턴은 많은 양의 코드에 접근할 수 있는 단순화된 인터페이스를 제공한다.

4. 2. 6. 플라이웨이트 패턴 (Flyweight)

플라이웨이트는 유사한 객체를 대량으로 생성하고 조작하는 비용을 줄인다.

4. 2. 7. 프록시 패턴 (Proxy)

프록시는 다른 객체에 대한 자리 표시자(대역)를 제공하여 접근을 제어하고, 비용을 줄이며, 복잡성을 줄인다.

4. 3. 행동 패턴 (Behavioral Patterns)

대부분의 행동 패턴은 객체 간의 통신 및 책임 분담과 관련된 문제를 해결하는 데 중점을 둔다. 각 패턴은 객체들이 상호작용하는 방식에 대한 유연하고 재사용 가능한 해결책을 제공한다. 주요 행동 패턴은 다음과 같다.

  • 책임 연쇄 패턴: 요청을 처리할 수 있는 객체가 처리하고, 처리하지 못하면 다음 객체로 넘기는 방식이다.
  • 커맨드 패턴: 요청 자체를 객체로 캡슐화하여 처리하는 방식이다.
  • 해석자 패턴: 특정 언어의 문법을 정의하고 해석하는 구조를 제공한다.
  • 반복자 패턴: 컬렉션의 내부 구조를 노출하지 않고 요소들에 순차적으로 접근하는 방법을 제공한다.
  • 중재자 패턴: 객체 간의 복잡한 상호 의존성을 줄이기 위해 중재 객체를 두어 통신을 관리한다.
  • 메멘토 패턴: 객체의 내부 상태를 저장하여 이전 상태로 복원할 수 있는 기능을 제공한다. (실행 취소 기능 구현에 사용된다.)
  • 옵저버 패턴: 한 객체의 상태가 변하면 의존하는 다른 객체들에게 자동으로 알림이 가도록 하는 일대다 의존성을 정의한다.
  • 상태 패턴: 객체의 내부 상태에 따라 행동을 변경할 수 있게 한다.
  • 전략 패턴: 알고리즘들을 각각의 클래스로 캡슐화하고, 필요에 따라 동적으로 교체하여 사용할 수 있게 한다.
  • 템플릿 메서드 패턴: 알고리즘의 골격은 상위 클래스에서 정의하고, 일부 단계는 하위 클래스에서 구현하도록 한다.
  • 방문자 패턴: 객체 구조는 변경하지 않으면서 새로운 기능을 추가할 수 있도록, 처리 로직을 분리된 방문자 객체에 정의한다.

4. 3. 1. 책임 연쇄 패턴 (Chain of Responsibility)

책임 연쇄 패턴 (Chain of Responsibility)은 여러 개의 처리 객체가 사슬처럼 연결되어 있는 구조를 가진다. 어떤 요청이 들어왔을 때, 한 객체가 해당 요청을 처리할 수 있다면 처리하고, 그렇지 못하면 연결된 다음 객체에게 자동으로 책임을 넘겨 요청 처리를 위임하는 방식이다. 이는 일련의 처리 객체들에게 명령을 순차적으로 위임하는 형태로 동작한다.

4. 3. 2. 커맨드 패턴 (Command)

커맨드 패턴 또는 명령 패턴은 요청(동작과 매개변수)을 객체로 캡슐화하는 행동 패턴이다. 여러 명령을 각각의 메서드로 직접 구현하는 대신, 하나의 추상 클래스나 인터페이스에 명령 실행을 위한 메서드를 정의하고 각 명령이 들어오면 그에 맞는 서브 클래스가 선택되어 실행되도록 한다. 즉, 동작과 매개변수를 캡슐화하는 객체를 생성하여 사용하는 방식이다.

4. 3. 3. 인터프리터 패턴 (Interpreter)

해석자 패턴은 문법 규칙을 클래스화한 구조를 통해 SQL 언어나 통신 프로토콜과 같은 특정 언어를 구현할 때 사용된다.

4. 3. 4. 이터레이터 패턴 (Iterator)

이터레이터 패턴(Iterator Pattern)은 반복이 필요한 자료 구조를 가지고 있는 요소들을 내부 구조를 드러내지 않으면서, 모두 동일한 인터페이스를 통해 순서대로 접근할 수 있도록 메서드를 이용하는 디자인 패턴이다. 즉, 객체의 내부 표현을 노출하지 않고 그 요소들에 순차적으로 접근할 수 있게 해준다.

4. 3. 5. 중재자 패턴 (Mediator)

중재자 패턴은 여러 클래스 간의 복잡한 상호작용을 직접 주고받는 대신, 하나의 '중재자' 역할을 하는 클래스에 모든 상호작용을 맡겨 처리하는 디자인 패턴이다. 이 중재자 클래스는 다른 클래스들의 메서드에 대한 정보를 가지고 있으며, 클래스 간의 통신을 대신 처리해준다. 이를 통해 각 클래스는 다른 클래스에 대해 자세히 알 필요 없이 중재자 클래스와만 통신하게 되므로, 클래스 간의 의존성을 낮추고 느슨한 결합을 가능하게 한다.

4. 3. 6. 메멘토 패턴 (Memento)

메멘토 패턴(Memento Pattern) 또는 기념품 패턴은 객체를 이전 상태로 복원하는 기능, 즉 실행 취소(Undo) 기능을 제공하는 디자인 패턴이다. 클래스 설계 관점에서 객체의 특정 시점 상태 정보를 외부에 저장했다가 필요할 때 해당 상태로 되돌릴 수 있도록 한다.

4. 3. 7. 옵저버 패턴 (Observer)

옵저버 패턴은 어떤 클래스에 변화가 일어났을 때, 이를 감지하여 다른 클래스에 통보해주는 디자인 패턴이다. 이는 게시/구독 패턴으로도 설명될 수 있으며, 여러 개의 옵저버 객체가 특정 객체의 상태 변화나 이벤트 발생을 지켜보고 자동으로 알림을 받을 수 있게 한다.

4. 3. 8. 상태 패턴 (State)

상태 패턴(State Pattern)은 객체의 내부 상태가 변경될 때 행동을 변경하도록 허용하는 디자인 패턴으로, 동일한 동작을 객체의 상태에 따라 다르게 처리해야 할 때 사용된다.

4. 3. 9. 전략 패턴 (Strategy)

전략 패턴은 여러 알고리즘을 정의하고 각각을 하나의 클래스캡슐화하여, 프로그램 실행 중에 필요에 따라 서로 교환하거나 선택하여 사용할 수 있도록 하는 디자인 패턴이다.

4. 3. 10. 템플릿 메서드 패턴 (Template Method)

알고리즘의 골격을 추상 클래스에서 정의하고, 구체적인 내용은 하위 클래스에서 구현하도록 하는 디자인 패턴이다.

4. 3. 11. 방문자 패턴 (Visitor)

방문자 패턴 (Visitor Pattern)은 각 클래스의 데이터 구조로부터 처리 기능을 분리하여 별도의 방문자(visitor) 클래스로 만드는 방식이다. 이 방문자 클래스의 메서드가 각 클래스를 돌아다니며 특정 작업을 수행하도록 한다. 즉, 메서드 계층 구조를 하나의 객체(방문자)로 이동시켜 알고리즘을 객체 구조에서 분리하는 것이다.

5. 비판 및 논란

2005년, ACM SIGPLAN은 이 책의 저자들에게 그들의 작업이 "프로그래밍 실무와 프로그래밍 언어 설계"에 미친 영향력을 인정하여 그 해의 프로그래밍 언어 업적상을 수여했다.[7]

하지만, 일반적으로 소프트웨어 디자인 패턴의 개념과, 특히 ''디자인 패턴'' 책 자체에 대한 비판도 제기됐다. ''디자인 패턴''에 대한 주요 비판 중 하나는 책에서 소개하는 패턴들이 C++와 같이 특정 언어에서 부족한 기능을 보완하기 위한 해결책에 불과하다는 점이다. 이로 인해 우아한 추상화 기능을 사용하는 대신 길고 구체적인 패턴을 반복적으로 적용하게 되어, 프로그래머가 마치 "인간 컴파일러"처럼 작동하게 된다는 지적이 있다. 폴 그레이엄은 자신의 프로그램에서 패턴을 발견하는 것을 오히려 문제의 징조로 여긴다고 언급하며, "프로그램의 형태는 해결해야 할 문제만을 반영해야 한다. 코드에서 다른 규칙성이 보인다면, 이는 충분히 강력하지 않은 추상화를 사용하고 있다는 신호이며, 종종 손으로 작성해야 하는 매크로의 확장을 생성하고 있는 것과 같다"고 비판했다.[8]

피터 노빅은 ''디자인 패턴''에 소개된 23개의 패턴 중 16개가 Lisp나 Dylan과 같은 다른 프로그래밍 언어에서는 언어 자체의 기능으로 인해 훨씬 단순화되거나 아예 필요하지 않게 된다는 점을 지적했다.[9] Hannemann과 키찰레스 역시 유사한 관찰 결과를 발표했는데, 이들은 관점 지향 프로그래밍(AOP) 언어인 AspectJ를 사용하여 23개의 디자인 패턴 중 여러 개를 구현했다. 그 결과, 23개 패턴 중 17개 구현에서 코드 수준의 종속성이 제거되었으며, 이는 관점 지향 프로그래밍이 디자인 패턴의 구현을 단순화할 수 있음을 보여주는 것이었다.[10]

한편, 저자 중 한 명인 에리히 감마는 2009년 InformIT과의 인터뷰에서 2005년에 저자들이 책을 어떻게 개선할지에 대해 논의했다고 밝혔다. 당시 논의에서는 일부 패턴을 재분류하고, 확장 객체/인터페이스, 의존성 주입, 유형 객체, 널 객체와 같은 몇 가지 새로운 패턴을 추가하는 방향으로 의견이 모아졌다. 감마는 개인적으로 싱글톤 패턴을 제거하고 싶어 했으나, 저자들 간의 완전한 합의에는 이르지 못했다고 언급했다.[11]

참조

[1] 서적 Pro ODP .NET for Oracle Database 11g https://doi.org/10.1[...] Apress 2010-01-26
[2] 서적 2017 IEEE International Conference on Software Quality, Reliability and Security (QRS) 2017
[3] 서적 Scala Design Patterns: Patterns for Practical Reuse and Design https://doi.org/10.1[...] Springer International Publishing 2013-01-26
[4] 간행물 Bad Smells of Gang of Four Design Patterns: A Decade Systematic Literature Review 2021-01-26
[5] 서적 Pitfalls of aspectJ implementations of some of the gang-of-four design patterns https://repositorium[...] Universidad de Extremadura 2004-01-26
[6] 문서 Richard Helm http://c2.com/cgi/wi[...]
[7] 웹사이트 SIGPLAN FY '05 Annual Report http://www.sigplan.o[...]
[8] conference Revenge of the Nerds http://www.paulgraha[...] 2012-08-11
[9] conference Design Patterns in Dynamic Languages http://www.norvig.co[...]
[10] conference Design pattern implementation in Java and AspectJ http://hannemann.pbw[...]
[11] interview Design Patterns 15 Years Later: An Interview with Erich Gamma, Richard Helm, and Ralph Johnson http://www.informit.[...] 2009-10-22



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com