디자인 패턴 종합 정리 — GoF 23가지 패턴 완전 정복 (TOPCIT 대비)
이 문서는 TOPCIT 2026년 개정 평가구조 모의고사 1~8회(특히 8회 “디자인 패턴 특집”)에서 다룬 모든 디자인 패턴을 포함하여, GoF(Gang of Four, 에리히 감마 외 4인의 저자를 가리키는 명칭)가 1994년 저서 『Design Patterns』에서 정리한 23가지 디자인 패턴 전체를 체계적으로 정리한 종합 참고 문서입니다. 각 패턴마다 (1) 핵심 정의, (2) 구조(참여자), (3) 실무 활용 예시, (4) TOPCIT에서 자주 혼동되는 다른 패턴과의 비교를 포함했습니다.
0. 디자인 패턴이란 무엇인가
0.1 디자인 패턴의 정의와 목적
디자인 패턴은 소프트웨어 설계 과정에서 반복적으로 나타나는 특정 문제 상황에 대해, 여러 개발자들의 경험을 통해 검증된 재사용 가능한 해결책의 “형식(template)”을 가리킨다. 패턴 자체는 바로 가져다 붙일 수 있는 완성된 코드가 아니라, “이런 상황에서는 이런 구조로 설계하면 좋다”는 일반적인 지침이며, 실제 구현은 프로그래밍 언어와 프로젝트의 맥락에 맞게 조정되어야 한다.
디자인 패턴을 학습하고 활용하는 이유는 다음과 같다.
- 검증된 해법의 재사용: 이미 여러 프로젝트에서 효과가 입증된 설계 방식을 매번 처음부터 고민하지 않고 재사용할 수 있다.
- 공통 어휘(Vocabulary)의 제공: “여기에 옵저버 패턴을 적용하자”라는 한마디로 개발자들 사이에 복잡한 설계 의도를 빠르게 전달할 수 있다.
- SOLID 원칙의 구체적 실현: 이 문제집에서 다룬 SRP, OCP, LSP, ISP, DIP(회차 5~7)와 같은 추상적인 설계 원칙들이, 디자인 패턴이라는 구체적인 코드 구조로 실현된다.
0.2 GoF 패턴의 3대 분류
GoF의 23가지 패턴은 그 목적에 따라 크게 세 가지로 분류된다.
| 분류 | 핵심 질문 | 해당 패턴 (5+7+11=23개) |
|---|---|---|
| 생성 패턴(Creational) | “객체를 어떻게 생성할 것인가?” | 싱글턴, 팩토리 메서드, 추상 팩토리, 빌더, 프로토타입 (5개) |
| 구조 패턴(Structural) | “객체와 클래스를 어떻게 조합하여 더 큰 구조를 만들 것인가?” | 어댑터, 브릿지, 컴포지트, 데코레이터, 퍼사드, 플라이웨이트, 프록시 (7개) |
| 행위 패턴(Behavioral) | “객체들이 어떻게 상호작용하고 책임을 분배할 것인가?” | 책임연쇄, 커맨드, 인터프리터, 이터레이터, 미디에이터, 메멘토, 옵저버, 스테이트, 전략, 템플릿 메서드, 비지터 (11개) |
이 세 가지 분류의 핵심 질문을 먼저 기억해두면, 처음 보는 패턴을 만나더라도 “이것이 생성/구조/행위 중 어디에 속하는가”를 통해 그 패턴의 대략적인 목적을 빠르게 유추할 수 있다.
0.3 TOPCIT 문제 풀이 전략: 패턴을 구분하는 3단계 질문
디자인 패턴 문제를 풀 때는 다음 순서로 접근하면 효과적이다.
- “무엇에 관한 문제인가?” — 객체 생성? 구조 조합? 행위·책임 분배? (3대 분류 판별)
- “핵심 키워드가 무엇인가?” — 문제 지문에서 “오직 하나만”, “여러 제품군”, “복제”, “인터페이스 변환”, “기능 추가”, “접근 제어”, “상태에 따라”, “요청을 캡슐화” 등의 결정적 키워드를 찾는다.
- “구조가 비슷한 다른 패턴과 어떻게 다른가?” — 특히 어댑터/데코레이터/프록시, 전략/스테이트, 팩토리메서드/추상팩토리와 같이 구조가 유사한 패턴들은 반드시 “목적(의도)”의 차이로 구분해야 한다.
1. 생성 패턴(Creational Patterns) — 5가지
생성 패턴은 객체를 생성하는 과정 자체를 캡슐화하여, “어떤 클래스의 인스턴스를 생성할 것인가”를 시스템의 나머지 부분으로부터 분리하는 것을 목표로 한다. 이를 통해 객체 생성 로직이 변경되어도 그 객체를 사용하는 코드는 영향을 받지 않으며, 시스템은 특정 구체 클래스에 대한 의존도를 낮출 수 있다.
1.1 싱글턴 패턴(Singleton Pattern)
핵심 정의: 클래스의 인스턴스가 오직 하나만 생성되도록 보장하고, 그 유일한 인스턴스에 대한 전역적인 접근점을 제공하는 패턴.
구조(참여자): 자기 자신의 유일한 인스턴스를 스스로 관리하는 하나의 클래스만으로 구성된다. 이 클래스는 생성자를 private으로 감추어 외부에서 new로 직접 생성하지 못하게 막고, 정적(static) 메서드(주로 getInstance())를 통해서만 그 유일한 인스턴스에 접근할 수 있게 한다.
실무 활용 예시: 데이터베이스 커넥션 풀, 애플리케이션의 전역 설정(Config) 객체, 로그 기록 객체(Logger), 캐시 관리자와 같이 애플리케이션 전체에서 상태를 공유해야 하는 자원.
TOPCIT 빈출 함정: 멀티스레드 환경에서 여러 스레드가 동시에 getInstance()를 처음 호출하면 인스턴스가 2개 이상 생성될 수 있는 경쟁조건이 발생할 수 있다(모의고사 8회 I-1, I-18). 이를 막기 위한 이중 검사 잠금(Double-Checked Locking)과 volatile 키워드의 역할을 함께 알아두어야 한다.
주의점: 싱글턴은 전역 상태를 만들어 코드 간의 숨겨진 의존성을 유발하고 단위 테스트를 어렵게 만들 수 있어, 최근에는 의존성 주입(Dependency Injection) 프레임워크를 통해 “싱글턴처럼 동작하지만 명시적으로 주입되는” 방식을 선호하는 경향도 있다.
1.2 팩토리 메서드 패턴(Factory Method Pattern)
핵심 정의: 객체 생성을 위한 인터페이스(메서드)만 상위 클래스에서 정의하고, 실제로 어떤 구체 클래스의 인스턴스를 생성할지는 하위 클래스가 결정하도록 위임하는 패턴.
구조(참여자): 생성할 제품의 공통 인터페이스(Product), 그 제품을 생성하는 추상 메서드를 정의한 상위 클래스(Creator), 그리고 그 팩토리 메서드를 재정의하여 구체적인 제품을 생성하는 하위 클래스(ConcreteCreator)로 구성된다.
실무 활용 예시: 문서 편집기에서 “새 문서 만들기” 기능을 상위 클래스에 정의하되, “워드 문서”용 편집기와 “스프레드시트”용 편집기가 각각 자신에게 맞는 문서 객체를 생성하도록 재정의하는 경우(모의고사 8회 I-19의 알림 발송 예시 참고).
TOPCIT 빈출 함정: 추상 팩토리 패턴과 자주 혼동된다. 팩토리 메서드는 “하나의 제품”을 생성하는 메서드 하나에 초점을 맞추는 반면, 추상 팩토리는 “서로 관련된 여러 제품군 전체”를 생성하는 팩토리 객체에 초점을 맞춘다는 차이를 정확히 구분해야 한다.
1.3 추상 팩토리 패턴(Abstract Factory Pattern)
핵심 정의: 서로 관련되거나 의존적인 여러 객체들의 “제품군(Family)”을, 그 구체적인 클래스를 지정하지 않고도 하나의 통일된 인터페이스를 통해 함께 생성할 수 있게 하는 패턴.
구조(참여자): 여러 제품을 생성하는 메서드들을 정의한 추상 팩토리 인터페이스(AbstractFactory), 이를 구현하여 특정 제품군(예: 윈도우 스타일)에 맞는 구체적인 제품들을 생성하는 구체 팩토리(ConcreteFactory), 그리고 각 제품의 추상 인터페이스와 구체 클래스들로 구성된다.
실무 활용 예시: UI 프레임워크에서 “윈도우 테마”와 “맥 테마”처럼 서로 다른 룩앤필(Look & Feel)을 일관되게 적용해야 할 때, 버튼·체크박스·스크롤바를 각 테마에 맞게 함께 생성하는 경우. 또는 데이터베이스 연동 코드에서 “MySQL용 팩토리”와 “PostgreSQL용 팩토리”가 각각 그 DBMS에 맞는 커넥션·쿼리 빌더·트랜잭션 객체를 함께 생성하는 경우.
TOPCIT 빈출 함정: 추상 팩토리는 내부적으로 여러 개의 팩토리 메서드를 포함하는 경우가 많아 두 패턴이 함께 사용되기도 한다는 것을 이해해두면 좋다(모의고사 8회 I-3).
1.4 빌더 패턴(Builder Pattern)
핵심 정의: 복잡한 객체를 생성하는 과정을 여러 단계로 분리하여, 동일한 생성 절차로도 서로 다른 구성(표현)의 결과물을 만들어낼 수 있게 하는 패턴.
구조(참여자): 객체 생성의 각 단계를 정의하는 빌더 인터페이스(Builder), 이를 구현하여 실제로 부품을 조립하는 구체 빌더(ConcreteBuilder), 그 조립 순서를 지정하는 감독자(Director, 생략되는 경우도 많음), 그리고 최종적으로 만들어지는 복잡한 객체(Product)로 구성된다.
실무 활용 예시: 여러 개의 선택적인 옵션(토핑, 사이즈, 온도 등)을 가진 “커스텀 커피 주문”을 조립하거나, HTTP 요청 객체처럼 URL·헤더·바디 등 여러 선택적 구성요소를 가진 객체를 단계별 메서드 체이닝(.setHeader().setBody().build())으로 생성하는 경우(모의고사 7회 I-12).
TOPCIT 빈출 함정: 빌더 패턴은 생성자에 너무 많은(특히 대부분 선택적인) 매개변수를 전달해야 하는 “텔레스코핑 생성자” 문제를 해결하기 위해 등장했다는 배경을 이해해두면 좋다.
1.5 프로토타입 패턴(Prototype Pattern)
핵심 정의: 이미 존재하는 객체를 새로 생성하는 대신 그대로 복제(clone)하여 새로운 객체를 만드는 패턴으로, 객체 생성 비용이 클 때 효율적이다.
구조(참여자): 복제 메서드(clone())를 정의한 프로토타입 인터페이스와, 이를 구현하여 실제 복제 로직을 담은 구체 클래스로 구성된다.
실무 활용 예시: 게임에서 동일한 종류의 몬스터 객체를 매번 복잡한 초기화 과정을 거쳐 새로 만드는 대신, 이미 초기화된 원본 몬스터를 복제하여 빠르게 생성하는 경우. 또는 데이터베이스에서 조회한 복잡한 설정 객체를 여러 곳에서 각각 다르게 수정해야 할 때, 매번 다시 조회하지 않고 복제하여 활용하는 경우.
TOPCIT 빈출 함정: 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy, 모의고사 3회 I-6, 8회 I-4)의 차이를 반드시 이해해야 한다. 원본 객체가 다른 가변 객체에 대한 참조를 포함하고 있다면, 얕은 복사만으로는 복제본과 원본이 그 내부 객체를 공유하게 되어 의도치 않은 부작용이 발생할 수 있다.
2. 구조 패턴(Structural Patterns) — 7가지
구조 패턴은 클래스와 객체를 어떻게 조합하여 더 크고 유연한 구조를 만들 것인가에 초점을 맞춘다. 이 중 어댑터·데코레이터·프록시 세 패턴은 모두 “기존 객체를 감싸는(Wrapping)” 유사한 구조를 취하지만 그 목적이 뚜렷이 다르므로, 이 셋을 반드시 비교하며 학습해야 한다.
2.1 어댑터 패턴(Adapter Pattern)
핵심 정의: 서로 호환되지 않는 인터페이스를 가진 클래스들이 함께 동작할 수 있도록, 그 사이에서 인터페이스를 변환해주는 패턴. 목적: 인터페이스 변환.
구조(참여자): 클라이언트가 기대하는 목표 인터페이스(Target), 이미 존재하지만 호환되지 않는 기존 클래스(Adaptee), 그리고 Target을 구현하면서 내부적으로 Adaptee를 호출하여 변환을 수행하는 어댑터(Adapter)로 구성된다.
실무 활용 예시: 레거시 시스템의 예전 API를 새로운 표준 인터페이스에 맞추어 통합할 때, 서드파티 라이브러리의 인터페이스를 자사 표준에 맞출 때(모의고사 5회 I-5, 8회 I-21의 여러 은행 API 통합 사례).
2.2 브릿지 패턴(Bridge Pattern)
핵심 정의: 추상화(무엇을 할 것인가)와 그 구현(어떻게 할 것인가)을 별도의 클래스 계층으로 분리하여, 이 둘이 서로 독립적으로 확장될 수 있게 하는 패턴. 목적: 클래스 폭발 방지, 두 축의 독립적 확장.
구조(참여자): 추상화 계층의 상위 클래스(Abstraction)와 그 확장(RefinedAbstraction), 구현 계층의 인터페이스(Implementor)와 그 구체 구현체(ConcreteImplementor)로 구성되며, Abstraction이 Implementor를 합성(필드로 소유)하는 것이 핵심이다.
실무 활용 예시: “도형의 종류(원, 사각형)”와 “렌더링 방식(래스터, 벡터)”처럼 두 개의 독립적으로 변화 가능한 축이 있을 때, 이를 하나의 상속 계층으로 합치면 조합의 수만큼 클래스가 기하급수적으로 늘어나는 것을 방지한다(모의고사 8회 I-5).
TOPCIT 빈출 함정: 어댑터 패턴과 구조적으로 유사(둘 다 인터페이스와 구현 클래스가 관련됨)해 보이지만, 어댑터는 “이미 존재하는 호환되지 않는 것을 맞추는” 사후적 해결책인 반면, 브릿지는 “설계 초기 단계부터 두 축을 의도적으로 분리해두는” 사전적 설계라는 차이가 있다.
2.3 컴포지트 패턴(Composite Pattern)
핵심 정의: 개별 객체(Leaf)와 여러 객체의 집합(Composite)을 동일한 인터페이스로 다룰 수 있게 하여, 클라이언트가 이 둘을 구분하지 않고 일관되게 처리할 수 있게 하는 패턴. 목적: 부분-전체 계층(트리) 구조의 통일된 처리.
구조(참여자): 개별 객체와 집합 객체가 공통으로 구현하는 인터페이스(Component), 자식이 없는 개별 객체(Leaf), 여러 Component를 자식으로 가질 수 있는 집합 객체(Composite)로 구성된다.
실무 활용 예시: 파일 시스템의 파일(Leaf)과 폴더(Composite, 파일이나 다른 폴더를 담을 수 있음), 조직도의 개별 직원과 부서, GUI의 개별 위젯과 패널(모의고사 8회 I-9).
TOPCIT 빈출 함정: 이 문제집에서 다룬 재귀적 관계(모의고사 4회 II-1, 6회 II-19)라는 데이터 모델링 개념이 객체지향 설계 차원에서 나타난 것이라는 점을 이해해두면 좋다.
2.4 데코레이터 패턴(Decorator Pattern)
핵심 정의: 기존 객체의 인터페이스는 그대로 유지한 채, 그 객체를 감싸서 새로운 책임(기능)을 동적으로 추가하는 패턴. 목적: 기능 추가.
구조(참여자): 기본 인터페이스(Component), 그 기본 구현체(ConcreteComponent), 그리고 Component를 구현하면서 내부에 또 다른 Component를 합성하여 새 기능을 덧붙이는 데코레이터(Decorator)로 구성된다.
실무 활용 예시: 커피 주문 시스템에서 “기본 커피”에 “샷 추가”, “휘핑크림 추가”와 같은 옵션을 동적으로 조합하는 경우, 자바의 입출력 스트림(BufferedReader가 FileReader를 감싸는 구조)이 대표적인 예다.
TOPCIT 빈출 함정(모의고사 8회 I-17): 프록시 패턴과 구조가 거의 동일(둘 다 원본과 동일한 인터페이스로 원본을 감쌈)하지만, 데코레이터는 “기능을 더한다”가 목적이고 프록시는 “접근을 통제한다”가 목적이라는 의도의 차이로 구분해야 한다.
2.5 퍼사드 패턴(Facade Pattern)
핵심 정의: 여러 개의 복잡한 하위 시스템 앞에 이를 단순화한 하나의 통합 인터페이스를 제공하는 패턴. 목적: 복잡성 은닉, 사용 편의성 제공.
구조(참여자): 여러 하위 시스템 클래스들에 대한 단순화된 창구 역할을 하는 퍼사드(Facade) 클래스 하나와, 그 내부에서 실제로 호출되는 여러 하위 시스템 클래스들로 구성된다.
실무 활용 예시: “홈시어터 켜기”라는 하나의 메서드가 내부적으로 프로젝터, 스피커, 조명을 각각 제어하는 경우(모의고사 8회 I-6), 복잡한 라이브러리의 API를 감싸 자주 쓰는 기능만 간단한 메서드로 제공하는 유틸리티 클래스.
2.6 플라이웨이트 패턴(Flyweight Pattern)
핵심 정의: 다수의 유사한 객체가 공통으로 갖는 속성(내재적 상태)을 하나의 공유 객체로 만들어 재사용함으로써, 대량의 객체 생성으로 인한 메모리 사용량을 절감하는 패턴. 목적: 메모리 효율화(공유).
구조(참여자): 공유되는 객체(Flyweight), 이를 관리하고 재사용하는 팩토리(FlyweightFactory), 그리고 공유되지 않고 클라이언트가 별도로 관리하는 외재적 상태로 구성된다.
실무 활용 예시: 워드프로세서의 각 문자마다 폰트·크기 정보를 공유 객체로 재사용하는 경우(모의고사 8회 I-15), 게임에서 수천 개의 동일한 총알이나 나무 객체의 공통 속성(모델, 텍스처)을 공유하는 경우.
2.7 프록시 패턴(Proxy Pattern)
핵심 정의: 실제 객체(Real Subject)에 대한 접근을 제어하기 위해, 그와 동일한 인터페이스를 가진 대리자(Proxy)를 두어 클라이언트의 요청을 대신 받는 패턴. 목적: 접근 제어.
구조(참여자): 공통 인터페이스(Subject), 실제 작업을 수행하는 실제 객체(RealSubject), 그리고 RealSubject에 대한 접근을 제어하며 필요시 그 인터페이스를 그대로 구현한 프록시(Proxy)로 구성된다.
실무 활용 예시: 접근 권한을 검사하는 보호 프록시, 무거운 객체의 생성을 지연시키는 가상 프록시, 반복 요청의 결과를 캐싱하는 캐싱 프록시(모의고사 8회 I-7, I-21), 원격 서버의 객체를 로컬처럼 접근하게 하는 원격 프록시.
TOPCIT 빈출 함정: 데코레이터·어댑터와의 3자 비교(모의고사 8회 I-17)를 반드시 기억할 것. “인터페이스가 다를 때 맞추기 위해(어댑터) / 기능을 더하기 위해(데코레이터) / 접근을 통제하기 위해(프록시)”라는 짧은 요약으로 암기하면 좋다.
표 2-1. 어댑터 · 데코레이터 · 프록시 3자 비교 (TOPCIT 최빈출 비교 문제)
| 구분 | 어댑터(Adapter) | 데코레이터(Decorator) | 프록시(Proxy) |
|---|---|---|---|
| 핵심 목적 | 인터페이스 변환 | 기능(책임) 추가 | 접근 제어 |
| 원본과의 인터페이스 관계 | 서로 다른 인터페이스를 연결 | 동일한 인터페이스 유지 | 동일한 인터페이스 유지 |
| 적용 시점 | 이미 만들어진 호환 안 되는 클래스가 있을 때(사후적) | 기존 기능에 새 책임을 유연하게 추가하고 싶을 때 | 자원 접근을 통제·최적화하고 싶을 때 |
| 대표 예시 | 레거시 API 통합, 서드파티 라이브러리 연동 | 커피 옵션 추가, 입출력 스트림 | 캐싱, 권한 검사, 지연 초기화, 원격 호출 |
3. 행위 패턴(Behavioral Patterns) — 11가지
행위 패턴은 객체와 클래스 사이의 상호작용 방식과 책임의 분배에 초점을 맞춘다. GoF 23패턴 중 가장 많은 수(11개)를 차지하며, 특히 전략 패턴과 스테이트 패턴은 구조가 거의 동일하여 TOPCIT에서 반드시 비교하며 학습해야 하는 대표적인 쌍이다.
3.1 전략 패턴(Strategy Pattern)
핵심 정의: 알고리즘군을 각각 별도의 클래스로 캡슐화하여 서로 교체 가능하게 만들고, 클라이언트가 실행 시점에 원하는 알고리즘(전략)을 선택하여 사용할 수 있게 하는 패턴. 목적: 알고리즘(행동)의 캡슐화와 교체 가능성. 선택 주체는 “외부(클라이언트)”.
구조(참여자): 여러 전략이 공통으로 구현하는 인터페이스(Strategy), 이를 구현한 여러 구체 전략(ConcreteStrategy), 그리고 Strategy를 합성하여 사용하는 컨텍스트(Context)로 구성된다.
실무 활용 예시: 결제 수단(신용카드, 계좌이체, 간편결제)에 따라 서로 다른 결제 처리 로직을 적용하는 경우(모의고사 8회 I-20), 정렬 알고리즘을 상황에 따라 교체하는 경우, 할인 정책을 회원 등급에 따라 다르게 적용하는 경우.
3.2 스테이트 패턴(State Pattern)
핵심 정의: 객체의 내부 상태를 별도의 상태 클래스들로 캡슐화하여, 그 상태에 따라 객체의 행동이 달라지도록 하고, 각 상태 객체가 스스로 다음 상태로의 전이까지 책임지는 패턴. 목적: 상태에 따른 행동 변화와 전이 관리. 결정 주체는 “객체 자기 자신(각 상태)”.
구조(참여자): 여러 상태가 공통으로 구현하는 인터페이스(State), 이를 구현한 여러 구체 상태(ConcreteState, 각자 다음 상태로의 전이 로직을 포함), 그리고 현재 상태를 합성하여 유지하는 컨텍스트(Context)로 구성된다.
실무 활용 예시: 신호등(빨강→초록→노랑, 모의고사 8회 I-13)이나 주문 상태(발급대기→사용가능→사용완료/기간만료, 모의고사 2·6·7회의 상태 다이어그램 문제들)와 같이, 이 문제집에서 여러 차례 다룬 상태 다이어그램을 실제 코드로 구현하는 표준적인 방법.
TOPCIT 최빈출 비교(모의고사 8회 I-16): 전략 패턴과 스테이트 패턴은 클래스 다이어그램이 거의 동일(인터페이스+합성)하지만, “누가, 언제 구현체를 결정하는가” 로 구분한다. 전략은 클라이언트가 명시적으로 선택하여 그 선택이 유지되고, 스테이트는 각 상태 객체가 스스로 다음 상태를 결정하여 시간에 따라 자동으로 전이된다.
3.3 옵저버 패턴(Observer Pattern)
핵심 정의: 하나의 객체(주체)의 상태가 변경될 때, 그 객체를 구독하고 있는 여러 관찰자(옵저버) 객체들에게 자동으로 변경 사실을 통지하는 패턴. 목적: 일대다 의존 관계에서의 상태 변화 통지.
구조(참여자): 옵저버 목록을 관리하고 상태 변화 시 통지하는 주체(Subject), 그리고 통지를 받아 처리하는 옵저버 인터페이스와 그 구현체들(Observer)로 구성된다.
실무 활용 예시: 게시-구독(Publish-Subscribe) 모델, React·Vue와 같은 프론트엔드 프레임워크의 반응형 데이터 바인딩, 이벤트 리스너 기반 프로그래밍, SIEM의 이상 징후 탐지 시 자동 경고(모의고사 4회 III-9, 모의고사 6회 I-9).
3.4 템플릿 메서드 패턴(Template Method Pattern)
핵심 정의: 알고리즘의 전체적인 골격(단계의 순서)은 상위 클래스에서 고정하여 정의하고, 그 알고리즘을 구성하는 일부 단계의 구체적인 구현만 하위 클래스가 재정의하도록 하는 패턴. 목적: 알고리즘 구조의 재사용과 일부 단계의 다형적 구현.
구조(참여자): 알고리즘의 골격을 정의한 템플릿 메서드와, 하위 클래스가 재정의할 추상 메서드(훅, Hook)들을 함께 가진 상위 클래스(AbstractClass), 그리고 그 훅 메서드들을 재정의하는 하위 클래스(ConcreteClass)로 구성된다.
실무 활용 예시: 급여 계산 시스템에서 “급여 명세서 출력”이라는 공통 골격은 상위 클래스에 두고, “실제 급여 계산 방식”만 직원 유형(개발자, 관리자)마다 다르게 재정의하는 경우(모의고사 8회 I-21).
TOPCIT 최빈출 비교(모의고사 7회 I-13): 전략 패턴과 유사한 목표(여러 알고리즘의 유연한 처리)를 갖지만, 전략 패턴은 “합성”을 통해, 템플릿 메서드는 “상속”을 통해 그 목표를 달성한다는 구현 메커니즘의 차이가 있다.
3.5 커맨드 패턴(Command Pattern)
핵심 정의: 요청(수행할 작업)을 하나의 독립된 객체로 캡슐화하여, 그 실행을 지연시키거나, 이력을 저장해 실행 취소를 지원하거나, 대기열에 쌓아 순차 처리할 수 있게 하는 패턴. 목적: 요청의 캡슐화, 발신자와 수신자의 분리.
구조(참여자): 실행 메서드를 정의한 커맨드 인터페이스(Command), 이를 구현하여 실제 수신자를 호출하는 구체 커맨드(ConcreteCommand), 커맨드를 호출하는 발신자(Invoker), 그리고 실제 작업을 수행하는 수신자(Receiver)로 구성된다.
실무 활용 예시: 리모컨의 각 버튼과 그에 연결된 동작(모의고사 8회 I-8), 실행 취소/다시 실행(Undo/Redo) 기능, 작업 대기열(Task Queue) 시스템, CI/CD 파이프라인의 각 배포 단계.
3.6 이터레이터 패턴(Iterator Pattern)
핵심 정의: 컬렉션의 내부 구조를 노출하지 않고도, 그 요소들을 순차적으로 접근할 수 있는 표준화된 방법을 제공하는 패턴. 목적: 순회 방법의 통일과 컬렉션 구현의 캡슐화.
구조(참여자): 순회 메서드(hasNext(), next())를 정의한 이터레이터 인터페이스, 이를 구현한 구체 이터레이터, 그리고 이터레이터를 생성하는 컬렉션(Aggregate)으로 구성된다.
실무 활용 예시: Java의 Iterator, Python의 for...in, C++의 반복자와 같이 대부분의 현대 언어에 표준 라이브러리로 내장(모의고사 8회 I-10). 배열, 연결 리스트, 트리, 해시 테이블 등 서로 다른 자료구조를 동일한 방식으로 순회.
3.7 미디에이터 패턴(Mediator Pattern)
핵심 정의: 여러 객체들이 서로 직접 참조하며 복잡하게 상호작용하는 대신, 하나의 중재자 객체를 통해서만 간접적으로 소통하도록 하여 객체 간의 결합도를 낮추는 패턴. 목적: 다대다(N:M) 상호작용을 일대다(1:N)로 단순화.
구조(참여자): 동료 객체들 간의 소통을 조율하는 중재자 인터페이스와 그 구현체(Mediator), 그리고 중재자를 통해서만 소통하는 여러 동료 객체(Colleague)로 구성된다.
실무 활용 예시: 항공관제탑(여러 비행기가 직접 통신하지 않고 관제탑을 통해서만 소통, 모의고사 8회 I-11), 채팅방 서버(여러 사용자가 직접 연결되지 않고 서버를 통해 메시지 교환), UI 다이얼로그의 여러 위젯 간 상호작용을 조율하는 컨트롤러.
3.8 메멘토 패턴(Memento Pattern)
핵심 정의: 객체의 내부 상태를 캡슐화를 깨뜨리지 않으면서도 외부에 저장해두었다가, 나중에 그 저장된 상태로 객체를 복원할 수 있게 하는 패턴. 목적: 캡슐화를 유지한 채 상태의 저장·복원.
구조(참여자): 상태를 생성·복원하는 원본 객체(Originator), 저장된 상태 스냅샷(Memento), 그리고 그 메멘토를 보관만 하고 내부를 들여다보지 않는 관리자(Caretaker)로 구성된다.
실무 활용 예시: 문서 편집기의 실행 취소(Undo, 모의고사 8회 I-12), 게임의 저장하기(Save)/불러오기(Load) 기능, 트랜잭션의 롤백(개념적으로 유사).
3.9 비지터 패턴(Visitor Pattern)
핵심 정의: 객체 구조(클래스 계층)는 그대로 유지하면서, 그 구조에 속한 여러 종류의 객체들에 대해 수행할 새로운 연산을 별도의 클래스(방문자)로 추가할 수 있게 하는 패턴. 목적: 클래스 변경 없이 새로운 연산 추가.
구조(참여자): 방문자를 받아들이는 accept() 메서드를 가진 여러 요소 클래스(Element), 그리고 각 요소 타입에 대한 처리 로직을 담은 방문자 인터페이스와 그 구현체(Visitor)로 구성된다.
실무 활용 예시: 여러 종류의 도형(원, 사각형)에 대해 “넓이 계산”, “화면 그리기”, “XML 내보내기”와 같은 새로운 연산을 기존 도형 클래스 수정 없이 추가하는 경우(모의고사 8회 I-14). 컴파일러의 추상구문트리(AST) 순회 및 처리.
TOPCIT 최빈출 포인트: “클래스 종류는 고정적이지만 연산이 자주 추가되는” 상황에는 적합하지만, “클래스 종류가 자주 추가되는” 상황에는 오히려 부적합(새 클래스 추가 시 모든 기존 방문자를 수정해야 함)하다는 트레이드오프를 이해해야 한다.
3.10 책임 연쇄 패턴(Chain of Responsibility Pattern)
핵심 정의: 하나의 요청을, 그 요청을 처리할 수 있는 잠재적인 여러 처리자(핸들러)들이 사슬처럼 연결된 구조 위에서 전달하며, 그 사슬을 따라가다가 처리할 수 있는 핸들러가 그 요청을 처리하게 하는 패턴. 목적: 요청 발신자와 수신자의 분리, 여러 처리자에게 순차적으로 처리 기회 부여.
구조(참여자): 요청 처리 메서드와 다음 핸들러에 대한 참조를 가진 핸들러 인터페이스(Handler), 이를 구현한 여러 구체 핸들러(ConcreteHandler)로 구성되며, 각 핸들러는 자신이 처리할 수 없는 요청을 사슬의 다음 핸들러에게 넘긴다.
실무 활용 예시: 여러 단계의 승인 절차(팀장 승인 → 부서장 승인 → 대표 승인, 각 금액 한도에 따라 처리자가 결정됨), 웹 프레임워크의 미들웨어 체인(인증 확인 → 로깅 → 실제 요청 처리), 예외 처리의 catch 블록 연쇄.
TOPCIT 참고: 이 문제집에서 다룬 3계층 아키텍처(웹서버-WAS-DB, 모의고사 5회 III-2)나 CI/CD 파이프라인의 여러 단계가 순차적으로 요청/데이터를 처리해나가는 구조와 개념적으로 유사한 흐름을 가진다.
3.11 인터프리터 패턴(Interpreter Pattern)
핵심 정의: 특정 언어의 문법 규칙을 클래스로 표현하고, 그 문법에 따라 작성된 문장(표현식)을 해석하고 실행할 수 있는 해석기를 정의하는 패턴. 목적: 특정 도메인 언어(DSL)의 해석 및 실행.
구조(참여자): 해석 메서드를 정의한 추상 표현식(AbstractExpression), 문법의 최종 단위를 처리하는 터미널 표현식(TerminalExpression), 문법의 규칙(예: AND, OR 연산)을 처리하는 비터미널 표현식(NonterminalExpression)으로 구성된다.
실무 활용 예시: 정규표현식 엔진, SQL 파서, 계산기의 수식 해석, 간단한 검색 쿼리 언어의 처리. 다만 문법이 복잡해질수록 클래스의 수가 크게 늘어나는 단점이 있어, 매우 복잡한 언어에는 파서 생성 도구(전용 파서 라이브러리)를 사용하는 것이 일반적이며, 인터프리터 패턴은 상대적으로 단순한 문법에 적합하다.
표 3-1. 전략 vs 스테이트 vs 템플릿 메서드 비교 (행위를 다루는 패턴들의 구분)
| 구분 | 전략(Strategy) | 스테이트(State) | 템플릿 메서드(Template Method) |
|---|---|---|---|
| 핵심 목적 | 알고리즘 교체 | 상태에 따른 행동 변화 및 전이 | 알고리즘 골격 재사용 |
| 구현 메커니즘 | 합성(Composition) | 합성(Composition) | 상속(Inheritance) |
| 구현체 선택 주체 | 외부(클라이언트)가 명시적으로 선택 | 각 상태 객체가 스스로 다음 상태 결정 | 하위 클래스가 일부 단계만 재정의 |
| 전형적 사례 | 결제 수단, 정렬 알고리즘 | 신호등, 주문 상태 | 급여 계산 골격 + 유형별 계산식 |
4. 전체 23패턴 한눈에 보기
| 분류 | 번호 | 패턴명 | 한 줄 목적 |
|---|---|---|---|
| 생성 | 1.1 | 싱글턴 | 인스턴스를 하나만 생성 |
| 생성 | 1.2 | 팩토리 메서드 | 하나의 제품 생성을 하위 클래스에 위임 |
| 생성 | 1.3 | 추상 팩토리 | 관련된 여러 제품군을 함께 생성 |
| 생성 | 1.4 | 빌더 | 복잡한 객체를 단계별로 조립 |
| 생성 | 1.5 | 프로토타입 | 기존 객체를 복제하여 생성 |
| 구조 | 2.1 | 어댑터 | 호환되지 않는 인터페이스를 변환 |
| 구조 | 2.2 | 브릿지 | 추상화와 구현을 독립적으로 확장 |
| 구조 | 2.3 | 컴포지트 | 개별 객체와 집합을 동일하게 취급 |
| 구조 | 2.4 | 데코레이터 | 기존 기능에 새 책임을 동적으로 추가 |
| 구조 | 2.5 | 퍼사드 | 복잡한 하위 시스템을 단순 인터페이스로 통합 |
| 구조 | 2.6 | 플라이웨이트 | 유사 객체의 공통 속성을 공유하여 메모리 절약 |
| 구조 | 2.7 | 프록시 | 실제 객체에 대한 접근을 통제 |
| 행위 | 3.1 | 전략 | 알고리즘군을 교체 가능하게 캡슐화 |
| 행위 | 3.2 | 스테이트 | 상태에 따라 행동과 전이를 캡슐화 |
| 행위 | 3.3 | 옵저버 | 상태 변화를 구독자에게 자동 통지 |
| 행위 | 3.4 | 템플릿 메서드 | 알고리즘 골격을 고정, 일부만 재정의 |
| 행위 | 3.5 | 커맨드 | 요청 자체를 객체로 캡슐화 |
| 행위 | 3.6 | 이터레이터 | 컬렉션 순회 방법을 표준화 |
| 행위 | 3.7 | 미디에이터 | 다대다 상호작용을 중재자로 단순화 |
| 행위 | 3.8 | 메멘토 | 캡슐화를 유지한 채 상태를 저장·복원 |
| 행위 | 3.9 | 비지터 | 클래스 변경 없이 새 연산을 추가 |
| 행위 | 3.10 | 책임 연쇄 | 요청을 처리자 사슬을 따라 전달 |
| 행위 | 3.11 | 인터프리터 | 특정 문법을 해석·실행 |
5. 학습 마무리 가이드
- 3대 분류의 핵심 질문(생성=어떻게 만들까, 구조=어떻게 조합할까, 행위=어떻게 협력할까)을 가장 먼저 떠올리면, 처음 보는 지문도 큰 범주에서부터 좁혀나갈 수 있다.
- TOPCIT에서 특히 자주 비교되는 3개 쌍은 반드시 표로 암기해둘 것: ① 어댑터·데코레이터·프록시(표 2-1), ② 전략·스테이트·템플릿 메서드(표 3-1), ③ 팩토리 메서드·추상 팩토리(1.2~1.3의 빈출 함정 참고).
- 이 문서에서 인용한 “모의고사 O회 O-O” 표시는 이 문제집(1~8회)에서 해당 패턴이 실제로 다뤄진 문항 번호이므로, 개념이 헷갈릴 때는 해당 회차의 문항으로 돌아가 정답 상세설명·오답 해설을 함께 복습하면 효과적이다.
- 실전에서는 지문에 등장하는 동사(캡슐화한다/통지한다/조립한다/위임한다/공유한다 등) 가 패턴을 구분하는 결정적 단서가 되는 경우가 많으므로, 각 패턴의 “핵심 정의”에 쓰인 동사를 눈여겨보는 훈련이 도움이 된다.
(본 문서는 2026년 개정 TOPCIT 평가구조를 기준으로 한 학습자 자체 제작 참고자료이며, 실제 출제 내용과는 다를 수 있습니다.)
작성 일자: 2026-09-09