프로그래밍 패턴
프로그래밍패턴
마지막 업데이트: 2026-06-18 · 11 min read
프로그래밍 패턴은 자주 반복되는 설계 문제에 붙인 이름이다. 보통 프로그래밍 패턴 암기식으로 사용되며 나쁘다라고 주장하며 한때의 유행이다라고 하는 사람들이 꽤 있다.
하지만 프로그래밍 패턴의 장점은 의사소통의 비용이 줄어든다.
"여기 전략 패턴으로 빼자",
"외부 SDK는 어댑터 패턴으로 감싸자",
"이 조회는 Repository보다 Query Facade가 낫다"처럼 말할 수 있기때문에 대화 비용을 줄인다.
이 문서는 패턴 하나하나를 전부 설명하는 본문이 아니라, 개인 위키의 패턴 인덱스다. 각 패턴의 자세한 내용은 별도 페이지로 뺀다. 패턴 문서가 길어지면 한 문서 안에서 찾기 어려워지고, 나중에 예제와 반례를 추가하기도 불편하다.
패턴을 볼 때는 이름보다는 먼저 다음을 생각해야한다.
무엇이 바뀌는가?
무엇을 숨길 것인가?
무엇을 교체할 것인가?
어디가 외부 시스템과 만나는 경계인가?
이 추상화가 실제 변경 비용을 줄이는가?
개인 메모: 패턴은 약간의 허세를 포함한다. 하지만 모든 전문직 언어가 그렇다.
패턴과 관용구(Idiom)의 차이
프로그래밍 관용구 특정 언어에서 자연스러운 작은 표현 방식이다. 패턴은 그보다 크고, 보통 여러 객체, 모듈, 계층 사이의 관계를 다룬다.
구분 | 설명 | 예시 |
|---|---|---|
원칙 | 판단 기준 | SOLID, DRY, YAGNI |
패턴 | 반복 문제의 해결 구조 | Strategy, Adapter, Repository, Retry |
이디엄 | 언어별 자연스러운 표현 | Python |
문법 | 언어가 허용하는 형식 |
|
같은 전략 패턴도 언어마다 다르게 생긴다.
Java/C#에서는 interface가 자연스럽고, Python에서는 callable이나 duck typing이 자연스럽다. 패턴 이름은 같아도 구현은 언어의 관용구에 맞춰야 한다.
GoF 패턴
GoF의 Design Patterns는 객체지향 코드에서 반복되던 해결책에 이름을 붙인 책이다.[1] GoF는 패턴을 생성, 구조, 행위 패턴으로 나눈다.
GoF 분류 | 대표 패턴 | 대략의 관심사 |
|---|---|---|
생성 패턴 | Factory Method, Abstract Factory, Builder, Prototype, Singleton | 객체를 어떻게 만들 것인가 |
구조 패턴 | Adapter, Decorator, Facade, Proxy, Bridge, Composite, Flyweight | 객체를 어떻게 조립할 것인가 |
행위 패턴 | Strategy, State, Observer, Command, Template Method, Iterator, Visitor | 객체들이 어떻게 협력할 것인가 |
GoF 패턴은 여전히 유용하지만, 실무 문서에서는 GoF만으로 부족하다. 웹, DB, 운영 환경에서는 Repository, DTO, Retry, Timeout, Circuit Breaker, Cache-Aside 같은 패턴이 더 자주 보인다. Fowler의 Patterns of Enterprise Application Architecture는 이런 엔터프라이즈 애플리케이션 패턴을 정리한 쪽이다.[2]
짧은 용어 풀이
패턴 문서에서 자주 나오는 말들이다. 여기서는 길게 설명하지 않고, 읽다가 막히지 않을 정도로만 적는다.
용어 | 뜻 |
|---|---|
정책(Policy) | 상황에 따라 바뀌는 판단 규칙. 할인 정책, 권한 정책, 배송비 정책처럼 "어떻게 결정할 것인가"에 해당한다. |
전략(Strategy) | 교체 가능한 알고리즘이나 정책. Strategy Pattern에서는 정책을 객체로 빼서 갈아끼운다. |
로깅(Logging) | 실행 중 일어난 일을 기록하는 것. 장애 분석, 감사, 디버깅에 쓴다. |
캐싱(Caching) | 자주 쓰는 값을 가까운 저장소에 잠시 보관하는 것. 빠르지만 무효화 문제가 생긴다. |
검증(Validation) | 입력값이나 상태가 규칙을 만족하는지 확인하는 것. API 요청, 폼 입력, 도메인 명령에서 자주 나온다. |
렌더러(Renderer) | 데이터를 화면, 이미지, HTML, PDF 같은 출력 형태로 바꾸는 역할. |
저장소(Storage) | 파일, DB, 캐시처럼 데이터를 보관하는 곳. 문맥에 따라 물리 저장소나 저장소 추상화를 뜻한다. |
외부 SDK | 결제사, 문자 발송사, 클라우드 업체가 제공하는 라이브러리. 내부 코드에 직접 퍼지면 교체가 어렵다. |
레거시 API | 오래된 시스템의 API. 새 코드와 인터페이스가 안 맞는 경우가 많아서 Adapter로 감싸기 좋다. |
횡단 관심사 | 여러 기능에 공통으로 걸치는 관심사. 로깅, 권한 검사, 캐싱, 측정, retry 같은 것들이다. |
도메인 | 프로그램이 다루는 업무 영역. 쇼핑몰이면 주문, 결제, 배송, 상품이 도메인이다. |
DDD 모델 | Domain-Driven Design에서 말하는 도메인 중심 모델. DB 테이블보다 업무 개념과 규칙을 먼저 본다. |
Entity | 식별자와 생명주기를 가진 도메인 객체. 같은 값이어도 ID가 다르면 다른 객체다. |
Value Object | ID보다 값 자체가 의미인 객체. 돈, 좌표, 기간, 이메일 주소 같은 것이 예다. |
DTO | Data Transfer Object. API 응답이나 프로세스 경계를 넘기기 위한 데이터 모양이다. |
Aggregate | 관련 Entity와 Value Object를 하나의 일관성 단위로 묶은 것. 보통 Repository의 저장 단위가 된다. |
API Handler | HTTP 요청을 받아 검증하고 적절한 서비스나 명령으로 넘기는 진입점. |
Command Handler | "주문 생성", "회원 탈퇴"처럼 변경을 일으키는 명령을 처리하는 객체나 함수. |
Middleware | 요청과 응답 사이에 끼어 공통 처리를 하는 계층. 로깅, 인증, CORS, 압축 등이 자주 들어간다. |
ORM | Object-Relational Mapping. 객체와 관계형 DB 테이블 사이를 매핑하는 도구. SQL을 몰라도 되게 해주지는 않는다. |
RPC | Remote Procedure Call. 네트워크 너머의 함수를 호출하듯 통신하는 방식. |
Lock | 동시에 접근하면 깨지는 자원을 잠그는 장치. DB row lock, mutex, distributed lock 등이 있다. |
Idempotency | 같은 요청을 여러 번 보내도 결과가 한 번 보낸 것과 같게 만드는 성질. Retry와 같이 자주 본다. |
Backoff | 재시도 간격을 점점 늘리는 방식. 장애 중인 시스템을 계속 두드리지 않기 위해 쓴다. |
Fallback | 주 경로가 실패했을 때 대신 쓰는 경로. 캐시 값 반환, 기본 응답, 대체 서버 호출 등이 있다. |
TTL | Time To Live. 캐시나 토큰이 살아 있는 시간. |
Stale data | 최신이 아닌 데이터. 캐시는 종종 stale data를 허용하는 대가로 빨라진다. |
실행 계획 | DB가 SQL을 어떤 방식으로 실행할지 정한 계획. 인덱스를 쓸지, 테이블을 훑을지 여기서 갈린다. |
트랜잭션 | 여러 DB 작업을 하나의 일관성 경계로 묶는 것. 성공하면 commit, 실패하면 rollback한다. |
구조 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
컴포지션 | 정책, 렌더러, 저장소, 검증기 | 상속 계층이 깊어지면 먼저 본다 |
전략 패턴 | 할인, 배송비, 권한, 정렬, 검증 | 알고리즘이나 정책이 자주 바뀔 때 |
어댑터 패턴 | 외부 SDK, 결제사, 파일 저장소, 레거시 API | 외부 인터페이스가 내부 코드에 새는 것을 막을 때 |
퍼사드 패턴 | 주문 생성, 회원 가입, 결제 완료 처리 | 복잡한 하위 시스템 앞에 단순한 진입점이 필요할 때 |
데코레이터 패턴 | 로깅, 캐싱, 권한 검사, 측정 | 기존 객체를 수정하지 않고 부가 기능을 붙일 때 |
제어 흐름 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
가드 클루즈(Guard Clause) | API handler, validation, command handler | 중첩 |
Result 패턴 | 파싱, 유효성 검사, 도메인 명령 | 실패가 예외가 아니라 업무 흐름일 때 |
상태 패턴 | 주문 상태, 게임 상태, 승인 워크플로우 | 상태별 행동과 전이가 복잡할 때 |
데이터 접근 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
Repository 패턴 | 주문, 회원, 상품 같은 aggregate 저장소 | 도메인 코드에서 DB 세부사항을 밀어낼 때 |
Query Facade | 관리자 화면, 대시보드, 목록 API | 읽기 전용 조회가 도메인 모델을 억지로 끌고 올 때 |
모델 경계 분리 | 웹 API, 외부 연동, DDD 모델 | DB, 도메인, API 응답의 변경 속도가 다를 때 |
운영 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
Retry | HTTP client, DB command, 메시지 처리 | 재시도하면 성공할 수 있는 일시적 실패일 때 |
Timeout | 외부 API, DB, RPC, lock 획득 | 느린 의존성이 전체 시스템을 붙잡을 때 |
Circuit Breaker | 결제사 API, 인증 서버, 원격 서비스 | 실패하는 외부 의존성이 내 서버까지 죽일 때 |
Cache-Aside | 상품 상세, 설정값, 권한 목록 | 같은 데이터를 반복해서 읽고 약간 오래된 값을 허용할 때 |
실전 선택표
문제가 보일 때 | 먼저 볼 패턴 |
|---|---|
상속 계층이 깊어진다 | 컴포지션 |
정책이나 알고리즘이 자주 바뀐다 | 전략 패턴 |
외부 SDK 모양이 내부 코드에 퍼진다 | 어댑터 패턴 |
하위 시스템 호출 순서가 복잡하다 | 퍼사드 패턴 |
부가 기능을 원래 객체 수정 없이 붙이고 싶다 | 데코레이터 패턴 |
중첩 | Guard Clause |
실패를 호출자가 직접 처리해야 한다 | Result 패턴 |
상태별 행동과 전이가 복잡하다 | 상태 패턴 |
도메인 코드에 DB 세부사항이 새어 나온다 | Repository 패턴 |
화면 조회가 도메인 모델을 억지로 끌고 온다 | Query Facade |
외부 호출이 가끔 실패한다 | Retry + Timeout |
외부 의존성 장애가 내 시스템까지 죽인다 | Circuit Breaker |
같은 데이터를 반복해서 읽는다 | Cache-Aside |
패턴 남용 신호
변형이 하나뿐인데 Strategy를 만든다.
외부 시스템이 하나뿐인데 Adapter 계층을 여러 겹 만든다.
단순 함수 호출을 Command 객체로 감싼다.
상태가 두 개뿐인데 State Pattern을 만든다.
CRUD 화면에 DDD, CQRS, Event Sourcing을 다 얹는다.
이름은 패턴인데 실제로는 책임을 숨기는 거대한 객체가 된다.
교과서적으로 말하자면 패턴은 실력 자랑용 장식이 아니다.
지금 코드가 실제로 겪는 변경 압력을 줄일 때만 의미있다.
개인 메모: 다만 프로그램 코드 설명할때 패턴으로 말하면, 멋있어 보이고 의뢰인이 돈을 더 잘 쳐주는 경향이 있다. 별 건 아니더라도 전문성처럼 보일때가 있다. 교과서적으로는 허세용이 아니다라고 하지만, 모든게 교과서대로는 아닌것이다.
같이 보기
객체지향_프로그래밍
프로그래밍 이디엄
컴포지션
데이터 지향 프로그래밍
SQL
컬럼형 데이터베이스
참고문헌
[1] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994.
https://www.informit.com/store/design-patterns-elements-of-reusable-object-oriented-9780201633610
[2] Martin Fowler. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002.
https://martinfowler.com/books/eaa.html
[3] Martin Fowler. Refactoring: Improving the Design of Existing Code. 2nd ed., Addison-Wesley, 2018.
https://martinfowler.com/books/refactoring.html
https://www.informit.com/store/refactoring-improving-the-design-of-existing-code-9780134757599
[4] Joshua Kerievsky. Refactoring to Patterns. Addison-Wesley, 2004.
https://www.informit.com/store/refactoring-to-patterns-9780321213358
[5] Eric Evans. Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley, 2003.
https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215
[6] Vaughn Vernon. Implementing Domain-Driven Design. Addison-Wesley, 2013.
https://books.google.com/books/about/Implementing_Domain_Driven_Design.html?id=X7DpD5g3VP8C
[7] Gregor Hohpe, Bobby Woolf. Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. Addison-Wesley, 2003.
https://www.enterpriseintegrationpatterns.com/
https://martinfowler.com/books/eip.html
[8] Michael T. Nygard. Release It!: Design and Deploy Production-Ready Software. 2nd ed., Pragmatic Bookshelf, 2018.
https://pragprog.com/titles/mnee2/release-it-second-edition/
[9] Brendan Burns. Designing Distributed Systems: Patterns and Paradigms for Scalable, Reliable Services. O’Reilly, 2018.
https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/
[10] Martin Kleppmann. Designing Data-Intensive Applications. O’Reilly, 2017.
https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/
[11] Chris Richardson. Microservices Patterns: With Examples in Java. Manning, 2018.
https://www.manning.com/books/microservices-patterns
https://microservices.io/patterns/
[12] Mark Seemann, Steven van Deursen. Dependency Injection Principles, Practices, and Patterns. Manning, 2019.
https://www.manning.com/books/dependency-injection-principles-practices-patterns
[13] Robert C. Martin. Clean Architecture: A Craftsman’s Guide to Software Structure and Design. Prentice Hall, 2017.
https://books.google.com/books/about/Clean_Architecture.html?id=fwvetAEACAAJ
[14] John Ousterhout. A Philosophy of Software Design. Yaknyam Press, 2018.
https://web.stanford.edu/~ouster/cgi-bin/aposd2ndEdExtract.pdf
[15] Christopher Alexander, Sara Ishikawa, Murray Silverstein. A Pattern Language: Towns, Buildings, Construction. Oxford University Press, 1977.
https://global.oup.com/academic/product/a-pattern-language-9780195019193
[16] Microsoft Azure Architecture Center. Cloud Design Patterns.
https://learn.microsoft.com/en-us/azure/architecture/patterns/
분류: 프로그래밍 | 소프트웨어 공학 | 디자인 패턴 | WIKI