GoF 디자인 패턴 23가지
객체지향 설계에서 반복적으로 발생하는 객체 생성, 클래스·객체 조립, 객체 간 협력 문제를 생성·구조·행위 패턴으로 체계화한 재사용 가능한 설계 해법 카탈로그
Ⅰ. 개요 및 등장배경
가. GoF 디자인 패턴의 정의
GoF 디자인 패턴은 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 4인이 정리한 객체지향 설계 패턴 23가지를 의미한다. GoF라는 이름은 Gang of Four의 약칭이다. 디자인 패턴은 특정 언어의 라이브러리나 프레임워크가 아니라, 반복적으로 나타나는 설계 문제에 대해 검증된 객체지향 설계 구조를 일반화한 해법이다. 즉 코드 조각을 복사하는 방식이 아니라, 객체 책임, 생성 방식, 의존성 방향, 협력 관계를 어떻게 배치할지에 대한 설계 어휘다.
GoF 패턴 23가지는 목적에 따라 생성 패턴, 구조 패턴, 행위 패턴으로 분류된다. 생성 패턴은 객체 생성 방식을 캡슐화하여 구체 클래스 의존성을 줄이고 객체 생성의 유연성을 높인다. 구조 패턴은 클래스와 객체를 조합하여 더 큰 구조를 만들고, 기존 객체의 인터페이스를 변환하거나 기능을 동적으로 확장한다. 행위 패턴은 객체 간 책임 분배, 알고리즘 선택, 요청 전달, 상태 변화, 통지, 반복, 명령 처리처럼 객체 협력 방식을 정리한다.
기술사 답안에서 GoF 디자인 패턴은 단순 암기형으로 23개 이름을 나열하면 점수가 낮다. 각 패턴이 어떤 설계 문제를 해결하는지, 어떤 객체지향 원칙과 연결되는지, 과도한 사용 시 어떤 부작용이 있는지, 현대 프레임워크에서 어떻게 응용되는지 설명해야 한다. 예를 들어 Singleton은 전역 접근점을 제공하지만 테스트와 확장성을 해칠 수 있고, Strategy는 조건문을 줄이고 알고리즘 교체를 쉽게 하지만 클래스 수가 늘 수 있다. 패턴은 정답 템플릿이 아니라 설계 의사결정 도구로 이해해야 한다.
나. 등장 배경
- 객체지향 설계 복잡도 증가: 시스템 규모가 커지면서 클래스 간 결합도, 책임 분리, 확장성, 재사용성을 체계적으로 관리할 필요가 커졌다.
- 반복 설계 문제 축적: 객체 생성, 인터페이스 변환, 기능 확장, 요청 처리, 객체 상태 변화 같은 문제가 여러 프로젝트에서 반복적으로 발생했다.
- 설계 지식의 공유 필요: 숙련 개발자의 경험적 설계 해법을 공통 용어로 정리하여 팀 간 의사소통 비용을 줄일 필요가 있었다.
- 재사용성과 유지보수성 요구: 기능 변경에 강하고 코드 수정 범위를 줄이는 설계 구조가 소프트웨어 품질의 중요한 요소가 되었다.
- 프레임워크 설계 기반: GUI, 웹, 엔터프라이즈 프레임워크에서 Factory, Observer, Template Method, Proxy 같은 패턴이 광범위하게 활용되었다.
- 설계 원칙 구체화: 개방폐쇄 원칙, 의존성 역전, 단일 책임, 인터페이스 분리 같은 원칙을 실제 구조로 구현하는 방법이 필요했다.
GoF 디자인 패턴은 객체지향 설계에서 반복되는 문제를 생성·구조·행위 3분류의 23개 패턴으로 정리한 설계 해법 집합이다.
패턴 이름 암기보다 객체 책임, 결합도 완화, 확장성, 변경 영향 최소화, 과적용 위험까지 함께 설명해야 한다.
Ⅱ. 구성도 및 구성요소
가. 구성도
좌측: 생성 패턴 5개
중앙: 구조 패턴 7개
우측: 행위 패턴 11개
하단: 설계 효과·주의점
나. 구성요소
| 구분 | 요소 | 설명 |
|---|---|---|
| 분류 | 생성 패턴 | 객체 생성 과정을 캡슐화하여 구체 클래스 의존성을 낮추고 생성 방식 변경에 유연하게 대응한다. |
| 분류 | 구조 패턴 | 클래스와 객체를 조합해 새로운 구조를 만들고, 인터페이스 변환·기능 확장·대리 접근을 지원한다. |
| 분류 | 행위 패턴 | 객체 간 역할과 책임, 요청 전달, 알고리즘 선택, 상태 변화, 통지, 반복 처리 방식을 정의한다. |
| 설계원칙 | 캡슐화 | 변경 가능성이 높은 생성 로직, 알고리즘, 상태, 요청 처리 방식을 객체 내부로 숨긴다. |
| 설계원칙 | 다형성 | 구체 구현 대신 추상 타입에 의존하여 실행 시점에 구현 객체를 교체할 수 있게 한다. |
| 설계원칙 | 낮은 결합도 | 클라이언트 코드가 구체 클래스, 복잡한 서브시스템, 특정 알고리즘에 강하게 묶이지 않도록 한다. |
| 품질속성 | 재사용성 | 검증된 설계 구조를 반복 활용하여 중복 설계와 중복 코드를 줄인다. |
| 품질속성 | 확장성 | 기존 코드를 크게 수정하지 않고 객체, 알고리즘, 기능, 상태를 추가할 수 있게 한다. |
| 운영관점 | 과적용 위험 | 불필요한 추상화와 클래스 수 증가로 이해도와 성능, 디버깅 난이도가 악화될 수 있다. |
GoF 패턴은 생성 5개, 구조 7개, 행위 11개로 구성되며 각각 객체 생성, 객체 조립, 객체 협력 문제를 해결한다.
패턴의 목적은 코드량 증가가 아니라 변경에 강한 객체 책임 배치와 설계 의사소통 표준화다.
Ⅲ. 동작방식 및 아키텍처
가. 생성 패턴 동작방식
생성 패턴은 객체 생성 시점과 생성 대상을 클라이언트 코드에서 분리한다. 클라이언트가 구체 클래스를 직접 생성하면 생성자 변경, 구현체 교체, 객체군 변경 시 코드 수정 범위가 넓어진다. Factory Method는 객체 생성을 하위 클래스 또는 팩토리 메서드에 위임하고, Abstract Factory는 관련 객체군을 일관성 있게 생성한다. Builder는 복잡한 객체를 단계적으로 조립하고, Prototype은 기존 객체를 복제해 생성 비용을 줄인다. Singleton은 특정 객체를 하나만 만들고 전역 접근점을 제공한다.
- Abstract Factory: 제품군 단위 객체 생성을 추상화하여 UI 테마, DB 벤더, 플랫폼별 객체군을 교체할 때 유용하다.
- Builder: 생성자 매개변수가 많거나 생성 단계가 복잡한 객체를 가독성 있게 조립한다.
- Factory Method: 객체 생성 책임을 하위 클래스나 팩토리 메서드에 위임하여 클라이언트 의존성을 낮춘다.
- Prototype: 객체 생성 비용이 크거나 런타임 객체 구성이 복잡할 때 복제로 새 객체를 만든다.
- Singleton: 설정, 로깅, 캐시처럼 하나의 인스턴스가 필요한 경우 사용하나 전역 상태와 테스트 어려움에 주의한다.
나. 구조 패턴 동작방식
구조 패턴은 기존 클래스와 객체를 조합하여 유연한 구조를 만든다. Adapter는 호환되지 않는 인터페이스를 클라이언트가 기대하는 인터페이스로 변환한다. Bridge는 추상과 구현을 분리하여 두 축이 독립적으로 확장되게 한다. Composite는 개별 객체와 객체 그룹을 동일하게 다루는 트리 구조를 만든다. Decorator는 상속 대신 객체 감싸기로 기능을 동적으로 추가한다. Facade는 복잡한 서브시스템에 단순한 진입점을 제공한다. Flyweight는 공유 가능한 내부 상태를 분리하여 메모리를 절약한다. Proxy는 실제 객체 접근을 제어하거나 지연 로딩, 원격 호출, 보안 검사를 담당한다.
다. 행위 패턴 동작방식
행위 패턴은 객체 간 메시지 흐름과 책임 배분을 정리한다. Chain of Responsibility는 요청을 처리할 수 있는 객체가 나올 때까지 체인으로 전달한다. Command는 요청을 객체로 캡슐화하여 큐잉, 취소, 로깅을 가능하게 한다. Iterator는 컬렉션 내부 구조를 노출하지 않고 순회 방법을 제공한다. Observer는 한 객체 상태 변화가 여러 객체에 통지되도록 한다. Strategy는 알고리즘을 객체로 분리하여 런타임 교체를 지원한다. Template Method는 알고리즘 골격을 상위 클래스에 두고 일부 단계를 하위 클래스가 구현하게 한다. Visitor는 객체 구조를 변경하지 않고 새로운 연산을 추가한다.
라. 패턴 선택 절차
디자인 패턴은 먼저 문제를 식별한 뒤 선택해야 한다. 객체 생성이 복잡하고 구현체 교체 가능성이 높다면 생성 패턴을 검토한다. 기존 인터페이스가 맞지 않거나 객체 조합과 기능 확장이 필요하면 구조 패턴을 검토한다. 조건문이 많고 객체 간 협력 흐름이 복잡하거나 알고리즘 교체가 잦다면 행위 패턴을 검토한다. 패턴 적용 전에는 단순 설계로 충분한지, 변경 가능성이 실제로 존재하는지, 팀이 이해할 수 있는 수준인지, 테스트와 성능에 문제가 없는지 확인해야 한다.
마. 적용 예시
생성 패턴은 생성 책임 분리, 구조 패턴은 객체 조합, 행위 패턴은 객체 협력과 알고리즘 교체를 담당한다.
패턴은 설계 문제를 해결하기 위한 선택지이며, 먼저 문제 맥락과 변경 가능성을 판단한 뒤 최소한으로 적용해야 한다.
Ⅳ. 실무적용 및 사례
가. 프레임워크에서의 활용
현대 프레임워크는 GoF 패턴을 직접 또는 변형된 형태로 널리 사용한다. 의존성 주입 컨테이너는 객체 생성과 생명주기 관리를 담당하므로 Factory와 Singleton 성격을 가진다. 웹 프레임워크의 요청 처리 파이프라인은 Chain of Responsibility와 유사하고, 이벤트 리스너 구조는 Observer와 연결된다. ORM의 지연 로딩은 Proxy 개념을 사용하고, 템플릿 엔진이나 추상 컨트롤러는 Template Method 구조를 가진다. 따라서 패턴을 이해하면 프레임워크 내부 구조를 더 쉽게 파악할 수 있다.
나. 엔터프라이즈 시스템 적용
엔터프라이즈 시스템에서는 변경 가능성이 높은 영역을 패턴으로 분리하는 것이 중요하다. 결제 방식, 할인 정책, 배송 정책처럼 업무 규칙이 자주 바뀌는 영역에는 Strategy를 적용할 수 있다. 외부 시스템 연계에는 Adapter와 Facade를 적용하여 외부 API 변경의 영향을 내부 도메인 모델에서 분리할 수 있다. 이벤트 기반 처리에는 Observer 또는 Mediator 개념을 적용해 주문, 결제, 재고, 알림 간 결합도를 낮춘다. 다만 모든 서비스에 무조건 패턴을 넣으면 클래스가 과도하게 늘어 유지보수가 어려워질 수 있다.
다. 유지보수와 리팩토링 사례
레거시 코드에서 긴 조건문과 switch문이 반복된다면 Strategy, State, Factory Method 적용을 검토할 수 있다. 특정 클래스가 너무 많은 외부 시스템을 직접 호출한다면 Facade 또는 Adapter로 분리할 수 있다. 기능 추가가 상속 계층을 복잡하게 만든다면 Decorator나 Composition 기반 구조로 전환할 수 있다. 다만 패턴 적용은 리팩토링의 결과여야 한다. 처음부터 모든 가능성을 예측해 추상화를 과도하게 만들면 현재 요구보다 복잡한 설계가 되어 생산성이 떨어진다.
라. 실무 체크포인트
- 문제 중심 적용: 패턴 이름을 먼저 정하지 말고 생성, 조립, 협력, 상태, 알고리즘 변경 문제를 먼저 식별한다.
- 과도한 추상화 방지: 변경 가능성이 낮은 영역에 패턴을 넣으면 클래스와 인터페이스만 늘어 복잡도가 증가한다.
- 테스트 가능성 확인: Singleton, 전역 상태, 정적 팩토리는 테스트 격리성을 떨어뜨릴 수 있으므로 주의한다.
- 프레임워크 기능 활용: DI 컨테이너, 이벤트 버스, AOP, 프록시 기능이 이미 제공하는 패턴을 중복 구현하지 않는다.
- 팀 공통 용어화: 설계 리뷰에서 “전략으로 분리”, “어댑터로 감싸기”, “퍼사드 제공”처럼 의사소통 도구로 활용한다.
- 성능 영향 검토: Proxy, Decorator, Chain 구조는 간접 호출과 객체 수 증가가 발생할 수 있어 고성능 영역에서 점검이 필요하다.
- 도메인 모델 우선: 패턴 자체보다 도메인 책임과 비즈니스 규칙의 명확한 배치가 먼저다.
GoF 패턴은 프레임워크, 엔터프라이즈 시스템, 리팩토링, 외부 연계, 이벤트 처리, 정책 교체 영역에서 실무 활용도가 높다.
좋은 적용은 클래스 수를 늘리는 것이 아니라 변경 가능성이 높은 지점을 격리하고 팀 의사소통을 명확하게 만드는 것이다.
Ⅴ. 비교분석 및 발전전망
가. GoF 23개 패턴 요약 비교
| 분류 | 패턴 | 해결 문제 |
|---|---|---|
| 생성 | Abstract Factory | 관련 객체군을 구체 클래스에 의존하지 않고 일관성 있게 생성한다. |
| 생성 | Builder | 복잡한 객체 생성 과정을 단계별로 분리하고 가독성을 높인다. |
| 생성 | Factory Method | 객체 생성 결정을 하위 클래스 또는 팩토리 메서드에 위임한다. |
| 생성 | Prototype | 기존 객체를 복제해 생성 비용과 복잡한 초기화 과정을 줄인다. |
| 생성 | Singleton | 하나의 인스턴스만 유지하고 전역 접근점을 제공한다. |
| 구조 | Adapter | 호환되지 않는 인터페이스를 클라이언트가 기대하는 형태로 변환한다. |
| 구조 | Bridge | 추상과 구현을 분리하여 두 축을 독립적으로 확장한다. |
| 구조 | Composite | 개별 객체와 객체 그룹을 동일한 인터페이스로 다룬다. |
| 구조 | Decorator | 상속 대신 객체 감싸기로 기능을 동적으로 추가한다. |
| 구조 | Facade | 복잡한 서브시스템에 단순한 통합 인터페이스를 제공한다. |
| 구조 | Flyweight | 공유 가능한 상태를 분리해 많은 객체의 메모리 사용을 줄인다. |
| 구조 | Proxy | 실제 객체 접근을 대리하여 지연 로딩, 보안, 원격 호출, 캐싱을 제공한다. |
| 행위 | Chain of Responsibility | 요청 처리 객체를 체인으로 연결해 처리 주체를 동적으로 결정한다. |
| 행위 | Command | 요청을 객체로 캡슐화하여 실행, 취소, 큐잉, 로깅을 가능하게 한다. |
| 행위 | Interpreter | 문법 규칙을 객체 구조로 표현하고 해석한다. |
| 행위 | Iterator | 컬렉션 내부 구조를 노출하지 않고 순회 방법을 제공한다. |
| 행위 | Mediator | 객체 간 직접 참조를 줄이고 중재 객체를 통해 협력하게 한다. |
| 행위 | Memento | 객체 내부 상태를 캡슐화한 채 저장·복원한다. |
| 행위 | Observer | 한 객체 상태 변화가 의존 객체들에 자동 통지되도록 한다. |
| 행위 | State | 상태별 행동을 객체로 분리하여 상태 변화에 따른 행위를 캡슐화한다. |
| 행위 | Strategy | 알고리즘을 객체로 분리하여 실행 시점에 교체 가능하게 한다. |
| 행위 | Template Method | 알고리즘 골격을 상위 클래스에 두고 세부 단계를 하위 클래스가 정의한다. |
| 행위 | Visitor | 객체 구조를 바꾸지 않고 새로운 연산을 추가한다. |
나. 생성·구조·행위 패턴 비교
| 구분 | 생성 패턴 | 구조 패턴 | 행위 패턴 |
|---|---|---|---|
| 주요 관심 | 객체를 누가 어떻게 만들 것인가 | 객체를 어떻게 조합하고 감쌀 것인가 | 객체들이 어떻게 협력하고 책임을 나눌 것인가 |
| 변경 지점 | 구체 클래스, 생성 절차, 객체군 | 인터페이스, 조립 구조, 접근 경로 | 알고리즘, 상태, 요청 흐름, 통지 방식 |
| 대표 패턴 | Factory Method, Builder, Singleton | Adapter, Decorator, Facade, Proxy | Strategy, Observer, Command, State |
| 효과 | 생성 책임 분리와 객체 생성 유연성 확보 | 재사용 가능한 조합 구조와 기능 확장 | 협력 구조 단순화와 알고리즘 교체 용이성 |
| 주의점 | 팩토리 남발과 전역 상태 주의 | 과도한 래핑과 구조 복잡도 주의 | 클래스 증가와 흐름 추적 어려움 주의 |
다. 발전전망
- 프레임워크 내재화: DI, AOP, 이벤트, 프록시, 템플릿 구조가 프레임워크에 내장되면서 개발자가 직접 구현하는 패턴 수는 줄어든다.
- 함수형·반응형 설계와 결합: Strategy, Command, Observer는 함수형 인터페이스, 이벤트 스트림, 리액티브 프로그래밍과 결합된다.
- 마이크로서비스 설계 확장: 서비스 간 통신, API Gateway, Saga, Circuit Breaker 같은 아키텍처 패턴과 함께 사용된다.
- 테스트 가능성 중심 재해석: Singleton과 전역 상태보다 의존성 주입, 인터페이스 분리, Mock 가능 구조가 선호된다.
- 도메인 중심 설계와 결합: 패턴 적용보다 도메인 책임과 비즈니스 규칙을 명확히 배치하는 DDD 관점이 중요해진다.
- 생성형 AI 시대의 설계 검증: AI가 생성한 코드도 패턴명만 맞는지보다 책임 분리, 결합도, 테스트 가능성을 검토해야 한다.
라. 답안 작성 관점
- 정의에서는 반복 설계 문제에 대한 재사용 가능한 객체지향 설계 해법이라고 정리한다.
- 구성도는 생성 5개, 구조 7개, 행위 11개를 문제 영역별로 배치하여 표현한다.
- 표에는 23개 패턴명, 해결 문제, 실무 적용 예시를 함께 제시하면 고득점 구조가 된다.
- 실무 설명에서는 프레임워크 내 활용, 리팩토링 적용, 외부 연계, 정책 교체, 이벤트 처리 사례를 연결한다.
- 한계에는 과도한 추상화, 클래스 수 증가, 성능 저하, 테스트 어려움, 패턴 남용을 포함한다.
GoF 디자인 패턴 23가지는 객체 생성, 구조 조합, 객체 협력 문제를 표준 설계 어휘로 정리하여 재사용성과 유지보수성을 높인다.
기술사 답안에서는 23개 이름 나열보다 분류 기준, 해결 문제, 실무 사례, 설계원칙, 과적용 위험을 구조적으로 제시해야 한다.
'소프트웨어공학' 카테고리의 다른 글
| 경영 전략과 산업 구조 분석의 정석: 마이클 포터의 5 Forces(산업 구조 분석 모형) (0) | 2026.07.07 |
|---|---|
| 소프트웨어 공학의 진화: 객체지향, CBD, AOP, MDA 설계 패러다임 (0) | 2026.07.06 |
| 비즈니스 리스크 관리의 핵심: 최신 IT 규제(AI Act, 개인정보보호법, 망분리 완화) (0) | 2026.07.04 |
| 데이터 간의 선형 관계 측정: 상관관계(Correlation) 개념 및 유형 (0) | 2026.07.03 |
| 기업 가치의 극대화: VBM(가치기반경영) 정의와 핵심 요소 (0) | 2026.07.03 |