# 언제 어떤 디자인 패턴을 써야 할까? GoF 23가지 디자인 패턴 완전 가이드

---

# # 서론 – “디자인 패턴은 알지만 언제 써야 할지 모른다”

소프트웨어 개발자 면접에서 **디자인 패턴**을 물어보는 경우가 잦습니다.

대부분의 지원자는 “Singleton, Factory Method, Observer …” 와 같은 정의는 외우고 있지만, **실제 프로젝트에서 언제 해당 패턴을 적용해야 하는지**는 고민합니다.

이번 글에서는 **GoF(Gang of Four) 디자인 패턴 23가지**를 **생성(Creational)**, **구조(Structural)**, **행위(Behavioral)** 로 구분하고, **각 패턴이 해결하는 문제와 사용 시점을 체크리스트 형태**로 정리합니다. 초보자도 바로 이해할 수 있도록 쉬운 예시와 함께 설명합니다. SEO 키워드 **디자인 패턴**, **GoF 디자인 패턴**, **디자인 패턴 사용 사례**를 자연스럽게 포함했습니다.

> 👉 관련 토론: [Reddit – When to Use Which Design Pattern? A Complete Guide to All 23 GoF Design Patterns](https://reddit.com/r/programming/comments/1pepblq/when_to_use_which_design_pattern_a_complete_guide/)

---

# # 1️⃣ 생성(Creational) 패턴 – 객체 생성 로직을 캡슐화한다

| 패턴 | 언제 쓰나요? | 핵심 아이디어 | 간단 예시 |

|------|--------------|--------------|----------|

| **Singleton** | 전역에서 하나의 인스턴스만 필요할 때 | 클래스가 스스로 하나만 만들도록 제한 | `Logger`, `ThreadPool` |

| **Factory Method** | 서브클래스마다 생성 로직이 다를 때 | 상위 클래스에 “생성 메서드”를 선언하고, 서브클래스가 구체 구현 | OS별 버튼(`WindowsButton`, `MacButton`) |

| **Abstract Factory** | 관련된 객체군을 일관되게 만들고 싶을 때 | 여러 `Factory Method`를 하나의 인터페이스에 묶음 | 테마별 UI 컴포넌트 세트(`DarkThemeFactory`, `LightThemeFactory`) |

| **Builder** | 복잡한 객체를 단계별로 만들 때 | 객체 생성 과정을 분리하고, 동일 절차를 재사용 | `HttpRequest` 빌더, `PizzaBuilder` |

| **Prototype** | 기존 객체를 복제해 새로운 객체를 만들 때 | 객체를 복제(clone)하는 메서드 제공 | 게임 캐릭터 복제, 문서 템플릿 복사 |

## # 사용 체크리스트

- **인스턴스가 하나만 필요합니까?** → `Singleton`

- **구현체가 자주 바뀔 가능성이 있나요?** → `Factory Method` / `Abstract Factory`

- **생성 과정이 복잡하고 단계가 명확한가요?** → `Builder`

- **비용이 큰 객체를 복제해 재사용하고 싶다면?** → `Prototype`

---

# # 2️⃣ 구조(Structural) 패턴 – 클래스와 객체를 효율적으로 조합한다

| 패턴 | 언제 쓰나요? | 핵심 아이디어 | 간단 예시 |

|------|--------------|--------------|----------|

| **Adapter** | 기존 인터페이스를 새 요구에 맞추고 싶을 때 | 인터페이스 변환기 | 레거시 API를 새로운 서비스에 연결 |

| **Bridge** | 구현부와 추상부를 독립적으로 확장하고 싶을 때 | 두 계층을 분리 | 데이터베이스와 UI를 별도 확장 |

| **Composite** | 객체를 트리 구조로 묶어 단일 객체처럼 다루고 싶을 때 | 부분‑전체 계층 | 파일 시스템 디렉터리 |

| **Decorator** | 객체에 동적으로 기능을 추가하고 싶을 때 | 기존 객체를 감싸서 기능 확장 | 스트림에 압축·암호화 기능 추가 |

| **Facade** | 복잡한 서브시스템을 간단히 사용하고 싶을 때 | 통합 인터페이스 제공 | 복잡한 결제 모듈을 하나의 메서드로 |

| **Flyweight** | 다수의 유사 객체가 메모리를 많이 차지할 때 | 공유 객체로 메모리 절감 | 텍스트 편집기의 문자 객체 |

| **Proxy** | 실제 객체에 대한 접근을 제어하거나 지연시킬 때 | 대리 객체 제공 | 원격 서비스 호출, 캐시 프록시 |

## # 사용 체크리스트

- **외부 시스템과 호환이 필요합니까?** → `Adapter`

- **구현과 추상을 독립적으로 확장하고 싶다면?** → `Bridge`

- **트리 구조를 단일 객체처럼 다루고 싶다면?** → `Composite`

- **기능을 동적으로 추가·삭제하고 싶다면?** → `Decorator`

- **복잡한 서브시스템을 단순화하고 싶다면?** → `Facade`

- **수많은 유사 객체가 메모리 부담을 주나요?** → `Flyweight`

- **접근 제어나 지연 로딩이 필요하면?** → `Proxy`

---

# # 3️⃣ 행위(Behavioral) 패턴 – 객체 간 책임과 알고리즘을 효율적으로 분배한다

| 패턴 | 언제 쓰나요? | 핵심 아이디어 | 간단 예시 |

|------|--------------|--------------|----------|

| **Chain of Responsibility** | 요청을 여러 객체에게 순차적으로 전달하고, 어느 하나가 처리하도록 할 때 | 체인 형태 핸들러 | 로그 레벨에 따라 다른 처리기 |

| **Command** | 요청을 객체로 캡슐화해 호출자와 수행자를 분리하고 싶을 때 | 명령 객체 저장·취소·재실행 가능 | UI 버튼 클릭 → 명령 객체 |

| **Interpreter** | 언어(문법) 해석이 필요할 때 | 문법 트리를 구성해 평가 | 수식 파서 |

| **Iterator** | 컬렉션 내부 구조를 노출하지 않고 순회하고 싶을 때 | 순회 인터페이스 제공 | `List` 순회 |

| **Mediator** | 객체 간 복잡한 직접 통신을 중앙 매개체로 관리하고 싶을 때 | 중재자를 통해 통신 | 채팅방 서버 |

| **Memento** | 객체 상태를 저장하고 복원하고 싶을 때 | 상태 스냅샷 제공 | 텍스트 편집기의 Undo |

| **Observer** | 객체 상태 변화에 따라 여러 객체가 자동으로 통지받아야 할 때 | 일대다 의존성 | 이벤트 리스너 |

| **State** | 객체의 내부 상태에 따라 행동이 바뀔 때 | 상태 객체로 행동 캡슐화 | TCP 연결 상태 |

| **Strategy** | 알고리즘군을 캡슐화해 런타임에 교체하고 싶을 때 | 전략 객체 교체 | 정렬 알고리즘 선택 |

| **Template Method** | 상위 클래스에서 골격을 정의하고, 하위 클래스가 구체 구현하도록 할 때 | 템플릿 메서드 정의 | 파일 입출력 흐름 |

| **Visitor** | 객체 구조를 변경하지 않고 새로운 연산을 추가하고 싶을 때 | 방문자 객체가 구조를 순회 | AST(추상 구문 트리) 분석 |

## # 사용 체크리스트

- **요청 흐름을 유연하게 구성하고 싶다면?** → `Chain of Responsibility`

- **명령을 기록·취소·재실행하고 싶다면?** → `Command`

- **문법·표현식 해석이 필요하면?** → `Interpreter`

- **컬렉션을 은닉하고 순회만 필요하면?** → `Iterator`

- **다수 객체 간 복잡한 상호작용을 중앙에서 관리하고 싶다면?** → `Mediator`

- **Undo/Redo 기능이 필요하면?** → `Memento`

- **상태 변화에 따라 자동 알림이 필요하면?** → `Observer`

- **동작이 상태에 따라 달라진다면?** → `State`

- **다양한 알고리즘을 교체 가능하게 하고 싶다면?** → `Strategy`

- **알고리즘 흐름은 고정, 세부 구현만 바꾸고 싶다면?** → `Template Method`

- **새로운 연산을 객체 구조에 손대지 않고 추가하고 싶다면?** → `Visitor`

---

# # 결론 – 디자인 패턴 선택, “문제 중심” 접근이 핵심

1️⃣ **문제 정의** – “내가 해결하고 싶은 문제는 객체 생성? 구조 조합? 행위 제어?”

2️⃣ **카테고리 선택** – 생성·구조·행위 중 해당되는 영역을 찾는다.

3️⃣ **체크리스트 적용** – 위 표의 질문에 ‘예’가 많을수록 그 패턴이 적합하다.

4️⃣ **프로토타입 구현** – 작은 예제로 먼저 검증하고, 실제 코드에 적용한다.

이 과정을 반복하면 면접에서도 “왜 이 패턴을 선택했는가?” 라는 질문에 자신 있게 답변할 수 있습니다.

> **지금 바로 실전 연습!**

> - 오늘 프로젝트에서 **Factory Method** 혹은 **Strategy** 중 하나를 적용해 보세요.

> - 코드 리뷰 시 동료에게 **Facade**·**Decorator** 사용 가능성을 제안해 보세요.

**디자인 패턴은 도구**이며, **올바른 도구를 적절한 시점에 쓰는 것이** 성공적인 소프트웨어 설계의 핵심입니다. 이번 가이드를 통해 23가지 **GoF 디자인 패턴**을 상황별로 매칭하고, 여러분의 코드 품질을 한 단계 끌어올리세요!

---

*SEO 키워드: **디자인 패턴**, **GoF 디자인 패턴**, **디자인 패턴 사용 사례***
