디자인 패턴: Elements of Reusable Object-Oriented Software(디자인 패턴: 재사용 가능한 객체지향 소프트웨어의 요소)(1994)는 소프트웨어 디자인 패턴을 설명한 소프트웨어 공학 서적이다. 에리히 감마, 리처드 헬름, 랄프 존슨, 존 블리사이드 등 4명이 저술하고 그레이디 부치가 서문을 썼다. 이 책은 2부로 구성되어 있으며, 첫 두 장은 객체지향 프로그래밍의 능력과 함정을 탐구하고, 나머지 장은 23개의 고전적인 소프트웨어 디자인 패턴을 설명하며, C++과 Smalltalk의 예제도 포함되어 있다.
소프트웨어 공학 분야에 영향을 미치고 객체지향 설계의 이론과 실무에 대한 중요한 자료로 간주되며, 50만 부 이상이 영어와 다른 13개 언어로 판매되었다. 저자는 종종 Gang of Four (GoF)라고 불린다.
이 책은 브루스 앤더슨이 운영하는 OOPSLA '90의 BoF(BoF) 세션 'Towards an Architecture Handbook'에서 에리히 감마와 리처드 헬름을 만나 공통의 관심사를 발견하면서 시작되었다. 이 책의 최초 출판일은 1994년 10월 21일이고, 저작권은 1995년이기 때문에 1994년에 출판되었음에도 불구하고 종종 1995년으로 인용된다. 이 책은 1994년 10월 오리건주 포틀랜드에서 열린 OOPSLA 회의에서 처음으로 대중에게 공개되었으며, 2012년 3월 현재 40쇄를 찍었다.
"구현이 아니라 인터페이스를 프로그래밍하라". (Gang of Four 1995:18) 상속보다 구성: '클래스 상속'보다 '객체 합성'을 지지하라. (Gang of Four 1995:20) 저자들은 구현에 대한 인터페이스의 장점으로 다음과 같이 주장하고 있다:
객체가 인터페이스를 따르는 한, 클라이언트는 사용하는 객체의 특정 유형을 의식하지 않는다. 클라이언트는 이러한 객체를 구현하는 클래스에 대해 알지 못한다. 인터페이스의 사용은 객체지향 프로그래밍의 핵심 기능인 동적 바인딩과 다형성(polymorphism)으로 이어진다.
저자들은 상속을 화이트박스 재사용이라고 부르는데, 화이트박스는 가시성을 의미한다. 이와는 대조적으로 저자들은 객체 구성(명확하게 정의된 인터페이스를 가진 객체가 다른 객체에 대한 참조를 얻는 객체에 의해 런타임에 동적으로 사용되는 것)을 블랙박스 재사용이라고 부른다.
저자들은 상속과 캡슐화 사이의 긴장에 대해 장황하게 설명하며, 그들의 경험에 따르면 설계자들이 상속을 너무 많이 사용한다고 말한다(Gang of Four 1995:20). 그 위험성을 다음과 같이 설명한다:
"상속은 하위 클래스를 부모 구현의 세부 사항에 노출시키기 때문에 "상속은 캡슐화를 깨뜨린다"고 흔히들 말한다"(Gang Four 1995:19). (Gang of Four 1995:19) 그들은 서브 클래스의 구현이 부모 클래스의 구현과 결합되어 부모 클래스의 구현을 변경하면 서브 클래스도 변경해야 한다고 경고하고 있다. 또한, 이를 피하는 방법으로 추상 클래스에서만 상속할 것을 주장하고 있는데, 이 경우 코드의 재사용이 최소화된다고 지적한다.
상속의 사용은 주로 기존 컴포넌트의 기능을 추가할 때 권장되며, 기존 코드의 대부분을 재사용하고 비교적 적은 양의 새로운 코드를 추가하는 것이 좋다.
저자의 말에 따르면, "위임"은 객체 구성의 극단적인 형태이며, 항상 상속 대신 사용할 수 있다. 위임에는 두 개의 객체가 포함된다. '발신자'는 '델리게이트'에 자신을 넘겨주고, 델리게이트가 발신자를 참조하도록 한다. 따라서 시스템의 두 부분 사이의 링크는 컴파일 때가 아니라 실행시에만 설정된다. 콜백 기사에는 델리게이트에 대한 더 자세한 정보가 있다.
저자는 제네릭(Ada, Eiffel, Java, C#, VB.NET, Delphi) 또는 템플릿(C++)으로도 알려진 소위 매개변수화된 타입에 대해서도 설명한다. 이러한 유형은 사용하는 다른 모든 유형을 지정하지 않고도 임의의 유형을 정의할 수 있게 해준다.
저자는 델리게이션과 파라미터화가 매우 강력하다는 것을 인정하면서도 경고를 덧붙인다:
"동적이고 고도로 매개변수화된 소프트웨어는 정적 소프트웨어보다 이해하기도 어렵고 구축하기도 어렵다. (Gang of Four 1995:21) 저자는 또한 한 객체가 다른 객체를 '가지고' 또는 '그 일부인'(집계 객체와 그 소유자가 동일한 수명을 갖는 것을 의미) '집계'와 한 객체가 단순히 다른 객체를 '알고' 있는 '지인'을 구분한다. 지인 관계는 '관련' 또는 '사용' 관계라고도 한다. 아는 객체들은 서로에게 조작을 요구할 수는 있지만, 서로에게 책임을 지지는 않는다. 아쿠아 인텐스는 집계보다 약한 관계로, 객체 간 결합이 훨씬 느슨하다는 것을 시사한다.
저자들은 C#이나 자바처럼 '클래스 라이브러리'를 사용하는 사람들이 있는 반면, '툴킷'이라는 용어를 사용한다. 그들의 말에 따르면, 툴킷은 객체 지향 서브 루틴 라이브러리에 해당하며, "프레임워크"는 특정 클래스 소프트웨어의 재사용 가능한 설계를 구성하는 협력적인 클래스 집합이다. 그들은 애플리케이션을 설계하는 것이 어렵고, 툴킷을 설계하는 것이 어렵고, 프레임워크를 설계하는 것이 가장 어렵다고 말한다.