design-pattern 시각적으로 이해하기
각 개념의 아키텍처를 애니메이션 다이어그램으로 살펴보세요. 카드를 클릭하면 더 깊은 내용을 확인할 수 있습니다.
Singleton
프로세스 전체에서 인스턴스를 하나만 유지하는 생성 패턴
Singleton은 클래스의 인스턴스가 프로세스 안에서 정확히 하나만 존재하도록 보장하고, 그 인스턴스에 접근할 전역적인 진입점을 만드는 생성 패턴입니다. 생성자를 숨기고 정적 메서드를 통해서만 객체를 내보내기 때문에, 누가 언제 호출하든 같은 인스턴스를 받게 됩니다.
Factory Method
객체 생성을 서브클래스에 위임하는 생성 패턴
Factory Method는 객체를 생성하는 코드를 직접 쓰는 대신, 생성 책임을 서브클래스에 넘기는 생성 패턴입니다. 상위 클래스(Creator)는 '무엇을 만들지'의 인터페이스만 정의하고, 실제로 '어떤 구체 객체를 만들지'는 하위 클래스(ConcreteCreator)가 결정합니다. 클라이언트는 Product 인터페이스에만 의존하므로 구체 클래스가 바뀌어도 호출 코드는 바뀌지 않습니다.
Abstract Factory
관련 객체 제품군을 일관되게 생성하는 인터페이스
Abstract Factory는 구체적인 클래스를 지정하지 않고, 서로 관련 있는 객체들의 제품군(family)을 한꺼번에 생성할 수 있게 해주는 생성 패턴입니다. 클라이언트 코드는 팩토리 인터페이스에만 의존하므로, 어떤 제품군이 만들어지는지는 런타임에 결정됩니다.
Builder
복잡한 객체의 생성 과정을 단계별로 분리하는 패턴
Builder는 복잡한 객체의 생성 과정을 단계별로 분리해서, 같은 생성 절차가 서로 다른 표현의 객체를 만들 수 있게 해주는 생성 패턴입니다. 생성자(constructor)에 매개변수를 한꺼번에 몰아넣는 대신, 필요한 부분을 하나씩 설정하고 마지막에 완성된 객체를 받습니다.
Adapter
호환되지 않는 인터페이스를 연결하는 구조 패턴
Adapter는 서로 호환되지 않는 두 인터페이스를 중간에서 연결해 주는 구조 패턴입니다. 클라이언트가 기대하는 인터페이스(Target)와 실제 사용하려는 클래스(Adaptee)의 인터페이스가 다를 때, Adapter가 그 사이에서 호출을 변환합니다. 전원 플러그 어댑터와 같은 원리입니다. 한국 콘센트에 미국 플러그를 꽂을 수 없지만, 어댑터를 끼우면 전기는 그대로 흐릅니다. 소프트웨어에서도 마찬가지로, 인터페이스만 맞지 않을 뿐 내부 기능은 쓸 수 있는 상황이 Adapter의 출발점입니다.
Facade
복잡한 서브시스템에 단순한 진입점을 만드는 구조 패턴
Facade는 복잡한 서브시스템 묶음에 단순화된 인터페이스를 씌우는 구조 패턴입니다. 클라이언트가 여러 클래스의 초기화 순서, 의존 관계, 호출 규약을 알 필요 없이 하나의 메서드로 원하는 결과를 얻게 해 줍니다. 호텔 프런트 데스크와 비슷합니다. 투숙객이 방 배정, 키 발급, 조식 예약을 각 부서에 따로 연락하지 않아도 프런트에서 한 번에 처리해 줍니다. 뒤에서 여러 부서가 움직이지만, 투숙객이 신경 쓸 필요는 없습니다.
Proxy
실제 객체에 대한 접근을 제어하는 대리 객체 패턴
Proxy는 실제 객체 앞에 대리 객체를 두어 접근을 제어하는 구조 패턴입니다. Client는 실제 객체와 같은 인터페이스를 통해 Proxy에 요청하고, Proxy가 접근 제어, 캐싱, 지연 로딩 같은 부가 로직을 수행한 뒤 필요하면 실제 객체에 위임합니다. 비서와 비슷합니다. 외부에서 임원에게 직접 연락하는 대신 비서를 거칩니다. 비서가 일정을 확인하고, 긴급도를 판단하고, 때로는 비서 선에서 처리합니다. 요청하는 쪽은 비서든 임원이든 같은 방식으로 연락하기 때문에 차이를 느끼지 못합니다.
Decorator
객체에 기능을 동적으로 덧붙이는 구조 패턴
Decorator는 객체를 같은 인터페이스의 래퍼로 감싸서, 원본 코드를 건드리지 않고 기능을 덧붙이는 구조 패턴입니다. 감싸는 쪽도 감싸이는 쪽도 동일한 인터페이스를 구현하기 때문에, 클라이언트 입장에서는 원본을 쓰는지 데코레이터를 쓰는지 알 필요가 없습니다.
Composite
개별 객체와 복합 객체를 동일하게 다루는 트리 구조 패턴
Composite는 개별 객체와 그 객체들의 그룹을 동일한 인터페이스로 다룰 수 있게 만드는 구조 패턴입니다. 트리 구조를 구성하면서, 클라이언트가 '이것이 말단인지 묶음인지' 신경 쓰지 않고 같은 메서드를 호출할 수 있게 합니다.
Observer
상태 변경을 구독자에게 자동으로 전파하는 행동 패턴
Observer 패턴은 객체의 상태가 바뀔 때 그 변화에 관심 있는 다른 객체들에게 자동으로 알려주는 구조입니다. 상태를 가진 쪽(Subject)과 그 변화를 지켜보는 쪽(Observer)을 분리해서, Subject는 누가 지켜보는지 몰라도 되고 Observer는 언제든 구독을 시작하거나 끊을 수 있습니다.
Strategy
알고리즘을 캡슐화해 런타임에 교체할 수 있게 만드는 행동 패턴
Strategy 패턴은 같은 목적을 달성하는 여러 알고리즘을 각각 별도의 클래스로 분리하고, 사용하는 쪽(Context)이 그 중 하나를 선택해서 실행하는 구조입니다. 알고리즘을 쓰는 코드와 알고리즘 자체를 분리하기 때문에, 새 알고리즘을 추가하거나 기존 것을 바꿀 때 호출하는 쪽을 수정하지 않아도 됩니다.
Command
요청을 객체로 캡슐화해 실행·취소·큐잉을 가능하게 하는 행동 패턴
Command 패턴은 '이것을 해라'라는 요청 자체를 하나의 객체로 만드는 구조입니다. 요청을 보내는 쪽(Invoker)은 그 요청이 구체적으로 무엇을 어떻게 하는지 모르고, 실제 작업을 수행하는 쪽(Receiver)은 누가 요청했는지 모릅니다. 요청이 객체가 되면 저장, 전달, 취소, 재실행이 가능해집니다.
Iterator
컬렉션의 내부 구조를 감추고 요소를 순서대로 탐색하는 패턴
Iterator는 컬렉션의 내부 구조를 노출하지 않으면서 그 요소들을 하나씩 순서대로 접근할 수 있게 해주는 행위 패턴입니다. 클라이언트는 next()와 hasNext() 같은 공통 인터페이스만 사용하고, 실제로 데이터가 배열에 있는지, 트리에 있는지, 해시맵에 있는지 신경 쓰지 않습니다.
Template Method
알고리즘의 골격은 고정하고 세부 단계만 서브클래스에 맡기는 패턴
Template Method는 알고리즘의 전체 구조를 부모 클래스의 메서드에 정의해 두고, 그 중 일부 단계의 구현을 서브클래스에 위임하는 행위 패턴입니다. 뼈대는 한 곳에서 관리하고, 살을 붙이는 방식만 달라지는 설계입니다.