디자인 패턴이란?
디자인 패턴은 소프트웨어 설계에서 반복적으로 등장하는 문제에 대한 해결책을 일종의 '템플릿'처럼 정리한 것이다. 단순한 코드 조각이 아니라, 특정 상황에서 적용할 수 있는 구조적 해법을 말한다. 이를 통해 코드의 재사용성, 유지보수성, 유연성을 높일 수 있다.
GoF(Gang of Four) 디자인 패턴은 디자인 패턴의 고전이라 할 수 있으며, 총 23가지 패턴이 다음 세 가지 분류로 나뉘어 있다.
- 생성 패턴 (Creational): 객체 생성 방식과 관련된 패턴
- 구조 패턴 (Structural): 클래스나 객체의 조합 방법을 정의
- 행위 패턴 (Behavioral): 객체 간의 책임과 커뮤니케이션 방식
생성 패턴 (Creational Patterns)
생성 패턴은 객체 생성 방식을 추상화하여, 시스템이 객체를 생성하고 조합하는 과정을 유연하게 만들도록 돕는 패턴이다.
복잡한 객체 생성 과정을 분리하거나, 생성 로직을 클라이언트 코드에서 감추는 데 유용하다.
- Singleton
- 하나의 인스턴스만 생성되도록 보장하고, 전역 접근 지점을 제공한다.
- ex. Logger, 설정 객체
- Factory Method
- 객체 생성을 서브클래스에게 위임해, 클라이언트 코드의 결합도를 낮춘다.
- ex. GUI 버튼 생성 (윈도우/웹)
- 3. Abstract Factory
- 관련된 객체 집합을 생성하는 인터페이스를 제공한다.
- ex. MacOS / Windows 스타일 버튼 + 체크박스
- Builder
- 복잡한 객체를 단계별로 생성하며, 동일한 생성 절차로 다양한 표현이 가능하다.
- ex. HTML 빌더, 메시지 생성기
- Prototype
- 기존 객체를 복제하여 새로운 객체를 생성한다.
- ex. 문서 복제, 도형 복사
구조 패턴 (Structural Patterns)
구조 패턴은 클래스나 객체를 조합하여 더 큰 구조를 만들 때 사용하는 패턴이다.
시스템의 유연성과 확장성을 높이기 위해, 클래스 간의 관계를 효율적으로 구성하는 데 초점을 둔다.
- Adapter
- 서로 호환되지 않는 인터페이스를 가진 클래스들을 연결해주는 패턴
- ex. 구형 인터페이스를 신형 시스템에 맞게 변환
- Bridge
- 구현부와 추상화를 분리하여 독립적으로 확장할 수 있도록 구성
- ex. 리모컨과 TV를 독립적으로 구현
- Composite
- 객체들을 트리 구조로 구성하여 전체-부분 관계를 동일하게 다루도록 함
- ex. 파일과 폴더를 계층 구조로 관리
- Decorator
- 객체에 동적으로 책임을 추가하는 구조
- ex. 커피에 시럽, 우유 등을 추가하는 구조
- Facade
- 복잡한 서브시스템에 대한 단순한 인터페이스를 제공
- ex. 서브 시스템을 감싸는 API 클래스
- Flyweight
- 동일한 객체를 공유하여 메모리를 절약하는 구조
- ex. 문자 렌더링, 반복되는 UI 컴포넌트
- Proxy
- 접근 제어, 로깅 등을 위해 대리 객체를 제공
- ex. 캐시 프록시, 보안 프록시, 원격 프록시
행위 패턴 (Behavioral Patterns)
행위 패턴은 객체 간의 책임 분배와 상호작용 방식에 초점을 맞춘다.
복잡한 로직을 분리하고, 객체 간 결합도를 낮추며, 유연한 흐름 제어를 가능하게 한다.
- Chain of Responsibility
- 요청을 처리할 수 있는 객체를 체인으로 연결하고, 순차적으로 전달
- ex. 이벤트 처리 체인, 필터 체인
- Command
- 요청을 캡슐화하여 객체로 만들고, 실행/취소 등을 유연하게 제어
- ex. 리모컨 버튼 → 명령 객체
- Interpreter
- 언어나 문법 규칙을 해석하는 클래스 구조를 구성
- ex. 간단한 계산기, 미니 DSL
- Iterator
- 컬렉션의 내부 구조를 노출하지 않고 요소들을 순차적으로 접근
- ex. Java의 Iterator, Python의 for-each
- Mediator
- 객체 간의 복잡한 관계를 중재자 하나에 집중시켜 의존성 제거
- ex. 채팅방의 중재 서버
- Memento
- 객체 상태를 외부에 저장하고, 필요할 때 복원 가능
- ex. 되돌리기(Undo) 기능
- Observer
- 한 객체의 상태 변화가 있을 때, 관련된 객체에 자동으로 알림
- ex. 이벤트 리스너, Pub/Sub 구조
- State
- 객체의 상태에 따라 행동이 달라지는 구조
- ex. 문 상태: 열림/닫힘/잠금에 따라 다르게 동작
- Strategy
- 알고리즘을 캡슐화하고 교체 가능하게 하여 유연성을 높임
- ex. 정렬 전략 (버블, 퀵 등)
- Template Method
- 알고리즘의 구조를 상위 클래스에 정의하고, 일부 단계를 하위 클래스가 구현
- ex. 게임 템플릿, JUnit 테스트 구조
- Visitor
- 객체 구조는 변경하지 않으면서, 기능을 추가할 수 있는 구조
- ex. 자료구조 순회하며 다른 연산 수행