프로그래밍 패턴
프로그래밍 패턴은 자주 반복되는 설계 문제에 붙인 이름이다. 패턴을 외워서 끼워 맞추는 방식이 싫다거나 한때의 유행이라고 말하는 사람들이 꽤 있다.
하지만 프로그래밍 패턴의 장점은 의사소통 비용을 줄인다는 데 있다.
출력 기능에 형식별 조건문이 계속 늘어난다고 하자. 변환 규칙을 별도 함수나 객체로 나누어 넘기면 출력 코드는 그대로 두고 형식만 바꿀 수 있는데, 이런 해결 구조를 전략 패턴이라고 부른다.
"여기 전략 패턴으로 빼자"는 바뀌는 처리 규칙을 본체와 나누어 교체할 수 있게 하자는 말이다.
"외부 SDK는 어댑터 패턴으로 감싸자"는 외부 라이브러리의 다른 호출 방식을 우리 코드의 약속에 맞추자는 말이다.
"이 조회는 Repository보다 Query Facade가 낫다"는 업무 객체를 조회·저장하는 구조보다 화면이 요구하는 조회 결과를 만드는 쪽에 초점을 맞추자는 말이다. 같은 문제와 역할을 공유하고 있을 때 이런 이름이 대화 비용을 줄인다.
이 페이지는 겪고 있는 문제에서 필요한 패턴 문서를 찾기 위한 안내다. 아래 선택표에서 가까운 상황을 고르고, 개별 문서에서 어떤 역할을 나누고 왜 그렇게 하는지 예제와 함께 읽으면 된다.
패턴 이름을 고르기 전에, 지금 코드에서 무엇이 불편한지부터 짚어 보자.
무엇이 바뀌는가?
무엇을 숨길 것인가?
무엇을 교체할 것인가?
어디가 외부 시스템과 만나는 경계인가?
이 추상화가 실제 변경 비용을 줄이는가?
개인 메모: 패턴은 약간의 허세를 포함한다. 하지만 모든 전문직 언어가 그렇다.
패턴과 관용구(Idiom)의 차이
프로그래밍 관용구는 특정 언어에서 자연스러운 작은 표현 방식이다. 패턴은 그보다 크고, 보통 여러 객체, 모듈, 계층 사이의 관계를 다룬다.
구분 | 설명 | 예시 |
|---|---|---|
원칙 | 판단 기준 | SOLID, DRY, YAGNI |
패턴 | 반복 문제의 해결 구조 | Strategy, Adapter, Repository, Retry |
이디엄 | 언어별 자연스러운 표현 | Python |
문법 | 언어가 허용하는 형식 |
|
- 구분
원칙
- 설명
판단 기준
- 예시
SOLID, DRY, YAGNI
- 구분
패턴
- 설명
반복 문제의 해결 구조
- 예시
Strategy, Adapter, Repository, Retry
- 구분
이디엄
- 설명
언어별 자연스러운 표현
- 예시
Python
with, C++ RAII, Rust?
- 구분
문법
- 설명
언어가 허용하는 형식
- 예시
if,class,interface
같은 전략 패턴도 언어마다 다르게 생긴다.
Java/C#에서는 인터페이스를 구현한 객체를 넘길 수 있고, Python에서는 함수나 필요한 동작을 제공하는 객체를 넘길 수 있다. 본체가 사용할 약속은 유지하되, 그 약속을 표현하는 방식은 언어의 관용구에 맞춘다.
GoF 패턴
GoF의 Design Patterns는 객체지향 코드에서 반복되던 해결책에 이름을 붙인 책이다.1 GoF는 패턴을 생성, 구조, 행위 패턴으로 나눈다.
GoF 패턴은 여전히 유용하지만, 실무 문서에서는 GoF만으로 부족하다. 웹, DB, 운영 환경에서는 Repository, DTO, Retry, Timeout, Circuit Breaker, Cache-Aside 같은 패턴이 더 자주 보인다. Fowler의 Patterns of Enterprise Application Architecture는 이 가운데 Repository나 DTO 같은 엔터프라이즈 애플리케이션 패턴을 정리한 책이다. Timeout, Circuit Breaker 같은 안정성 패턴은 Michael Nygard의 Release It!이 다루며, Cache-Aside는 Microsoft의 클라우드 설계 패턴 문서에서 다룬다.23
짧은 용어 풀이
패턴 문서에서 자주 나오는 말들이다. 여기서는 길게 설명하지 않고, 읽다가 막히지 않을 정도로만 적는다.
용어 | 뜻 |
|---|---|
정책(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한다. |
- 용어
정책(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 | 외부 인터페이스가 내부 코드에 새는 것을 막을 때 | |
주문 생성, 회원 가입, 결제 완료 처리 | 복잡한 하위 시스템 앞에 단순한 진입점이 필요할 때 | |
로깅, 캐싱, 권한 검사, 측정 | 기존 객체를 수정하지 않고 부가 기능을 붙일 때 |
- 패턴
- 주로 쓰는 곳
정책, 렌더러, 저장소, 검증기
- 한 줄 판단
상속 계층이 깊어지면 먼저 본다
- 패턴
- 주로 쓰는 곳
할인, 배송비, 권한, 정렬, 검증
- 한 줄 판단
알고리즘이나 정책이 자주 바뀔 때
- 패턴
- 주로 쓰는 곳
외부 SDK, 결제사, 파일 저장소, 레거시 API
- 한 줄 판단
외부 인터페이스가 내부 코드에 새는 것을 막을 때
- 패턴
- 주로 쓰는 곳
주문 생성, 회원 가입, 결제 완료 처리
- 한 줄 판단
복잡한 하위 시스템 앞에 단순한 진입점이 필요할 때
- 패턴
- 주로 쓰는 곳
로깅, 캐싱, 권한 검사, 측정
- 한 줄 판단
기존 객체를 수정하지 않고 부가 기능을 붙일 때
제어 흐름 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
API handler, validation, command handler | 중첩 | |
파싱, 유효성 검사, 도메인 명령 | 실패가 예외가 아니라 업무 흐름일 때 | |
주문 상태, 게임 상태, 승인 워크플로우 | 상태별 행동과 전이가 복잡할 때 |
- 주로 쓰는 곳
API handler, validation, command handler
- 한 줄 판단
중첩
if를 줄이고 실패 조건을 앞에서 걷어낼 때
- 주로 쓰는 곳
파싱, 유효성 검사, 도메인 명령
- 한 줄 판단
실패가 예외가 아니라 업무 흐름일 때
- 패턴
- 주로 쓰는 곳
주문 상태, 게임 상태, 승인 워크플로우
- 한 줄 판단
상태별 행동과 전이가 복잡할 때
데이터 접근 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
주문, 회원, 상품 같은 aggregate 저장소 | 도메인 코드에서 DB 세부사항을 밀어낼 때 | |
주문 확정, 장바구니 결제, 여러 집합체를 함께 바꾸는 명령 | 한 업무 처리의 변경을 모아 한 번에 커밋해야 할 때 | |
관리자 화면, 대시보드, 목록 API | 읽기 전용 조회가 도메인 모델을 억지로 끌고 올 때 | |
모델 경계 분리 | 웹 API, 외부 연동, DDD 모델 | DB, 도메인, API 응답의 변경 속도가 다를 때 |
- 주로 쓰는 곳
주문, 회원, 상품 같은 aggregate 저장소
- 한 줄 판단
도메인 코드에서 DB 세부사항을 밀어낼 때
- 주로 쓰는 곳
주문 확정, 장바구니 결제, 여러 집합체를 함께 바꾸는 명령
- 한 줄 판단
한 업무 처리의 변경을 모아 한 번에 커밋해야 할 때
- 주로 쓰는 곳
관리자 화면, 대시보드, 목록 API
- 한 줄 판단
읽기 전용 조회가 도메인 모델을 억지로 끌고 올 때
- 패턴
모델 경계 분리
DTO / Entity / Value Object- 주로 쓰는 곳
웹 API, 외부 연동, DDD 모델
- 한 줄 판단
DB, 도메인, API 응답의 변경 속도가 다를 때
운영 패턴
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
HTTP client, DB command, 메시지 처리 | 재시도하면 성공할 수 있는 일시적 실패일 때 | |
외부 API, DB, RPC, lock 획득 | 느린 의존성이 전체 시스템을 붙잡을 때 | |
결제사 API, 인증 서버, 원격 서비스 | 실패하는 외부 의존성이 내 서버까지 죽일 때 | |
결제사, 검색, 추천처럼 속도가 다른 의존성 호출 | 느린 의존성 하나가 연결 풀이나 동시 실행 칸을 다 차지할 때 | |
공개 API, 로그인, 외부 API 호출 한도 | 키별 요청 수를 제한하고 넘친 요청을 429로 거절해야 할 때 | |
상품 상세, 설정값, 권한 목록 | 같은 데이터를 반복해서 읽고 약간 오래된 값을 허용할 때 |
- 패턴
- 주로 쓰는 곳
HTTP client, DB command, 메시지 처리
- 한 줄 판단
재시도하면 성공할 수 있는 일시적 실패일 때
- 패턴
- 주로 쓰는 곳
외부 API, DB, RPC, lock 획득
- 한 줄 판단
느린 의존성이 전체 시스템을 붙잡을 때
- 주로 쓰는 곳
결제사 API, 인증 서버, 원격 서비스
- 한 줄 판단
실패하는 외부 의존성이 내 서버까지 죽일 때
- 패턴
- 주로 쓰는 곳
결제사, 검색, 추천처럼 속도가 다른 의존성 호출
- 한 줄 판단
느린 의존성 하나가 연결 풀이나 동시 실행 칸을 다 차지할 때
- 주로 쓰는 곳
공개 API, 로그인, 외부 API 호출 한도
- 한 줄 판단
키별 요청 수를 제한하고 넘친 요청을 429로 거절해야 할 때
- 주로 쓰는 곳
상품 상세, 설정값, 권한 목록
- 한 줄 판단
같은 데이터를 반복해서 읽고 약간 오래된 값을 허용할 때
UI 아키텍처 패턴
화면의 입력 처리, 표시, 화면 규칙을 어떻게 나눌지 정하는 패턴이다. 네 패턴의 비교와 연혁은 아키텍처 패턴 문서에 모았다.
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
Smalltalk식 데스크톱 UI, Rails나 ASP.NET Core MVC 같은 웹 프레임워크 | 입력 해석·모델·표시를 나눌 때. 고전 UI는 변경 알림을, 웹 MVC는 요청별 뷰 생성을 쓴다 | |
WinForms처럼 화면 로직을 따로 테스트하기 어려운 UI | 화면 규칙을 뷰 인터페이스 뒤에서 UI 없이 테스트하고 싶을 때 | |
WPF, .NET MAUI처럼 데이터 바인딩이 있는 UI | 바인딩 엔진이 있고 화면 상태와 명령을 ViewModel에 모을 때 | |
Elm, Redux 같은 단방향 상태 관리 | 화면 상태를 모델 하나에 두고 메시지로만 바꾸고 싶을 때 |
- 패턴
- 주로 쓰는 곳
Smalltalk식 데스크톱 UI, Rails나 ASP.NET Core MVC 같은 웹 프레임워크
- 한 줄 판단
입력 해석·모델·표시를 나눌 때. 고전 UI는 변경 알림을, 웹 MVC는 요청별 뷰 생성을 쓴다
- 패턴
- 주로 쓰는 곳
WinForms처럼 화면 로직을 따로 테스트하기 어려운 UI
- 한 줄 판단
화면 규칙을 뷰 인터페이스 뒤에서 UI 없이 테스트하고 싶을 때
- 패턴
- 주로 쓰는 곳
WPF, .NET MAUI처럼 데이터 바인딩이 있는 UI
- 한 줄 판단
바인딩 엔진이 있고 화면 상태와 명령을 ViewModel에 모을 때
- 패턴
- 주로 쓰는 곳
Elm, Redux 같은 단방향 상태 관리
- 한 줄 판단
화면 상태를 모델 하나에 두고 메시지로만 바꾸고 싶을 때
함수형 패턴
값과 함수를 조합해 처리 흐름을 만드는 패턴이다. 패러다임 전체는 함수형 프로그래밍 문서에서 다룬다.
패턴 | 주로 쓰는 곳 | 한 줄 판단 |
|---|---|---|
변환 파이프라인, 데이터 정제 단계 | 작은 함수의 출력을 다음 함수의 입력으로 이어 붙일 때 | |
설정값을 미리 묶은 함수, 콜백 | 인자 일부를 먼저 고정해 새 함수를 만들 때 | |
조회 결과, 선택 입력값 | 값이 없을 수 있음을 | |
파싱, 유효성 검사, 외부 호출 결과 | 실패를 예외 대신 반환값으로 다뤄야 할 때 | |
옵션, 결과, 목록 안의 값 변환 | 감싼 구조는 두고 안의 값에만 함수를 적용할 때 | |
실패하거나 비동기로 끝나는 계산의 연결 | 문맥을 가진 계산을 | |
합계, 병합, 병렬 집계 | 항목 순서는 유지한 채 부분 결과를 묶는 괄호 위치를 바꿔도 같아야 할 때 | |
집계, 트리 계산, 상태 재구성 | 컬렉션이나 재귀 구조를 값 하나로 줄일 때 |
- 패턴
- 주로 쓰는 곳
변환 파이프라인, 데이터 정제 단계
- 한 줄 판단
작은 함수의 출력을 다음 함수의 입력으로 이어 붙일 때
- 주로 쓰는 곳
설정값을 미리 묶은 함수, 콜백
- 한 줄 판단
인자 일부를 먼저 고정해 새 함수를 만들 때
- 패턴
- 주로 쓰는 곳
조회 결과, 선택 입력값
- 한 줄 판단
값이 없을 수 있음을
null대신 타입으로 드러낼 때
- 패턴
- 주로 쓰는 곳
파싱, 유효성 검사, 외부 호출 결과
- 한 줄 판단
실패를 예외 대신 반환값으로 다뤄야 할 때
- 패턴
- 주로 쓰는 곳
옵션, 결과, 목록 안의 값 변환
- 한 줄 판단
감싼 구조는 두고 안의 값에만 함수를 적용할 때
- 패턴
- 주로 쓰는 곳
실패하거나 비동기로 끝나는 계산의 연결
- 한 줄 판단
문맥을 가진 계산을
bind로 이어 붙일 때
- 패턴
- 주로 쓰는 곳
합계, 병합, 병렬 집계
- 한 줄 판단
항목 순서는 유지한 채 부분 결과를 묶는 괄호 위치를 바꿔도 같아야 할 때
- 패턴
- 주로 쓰는 곳
집계, 트리 계산, 상태 재구성
- 한 줄 판단
컬렉션이나 재귀 구조를 값 하나로 줄일 때
실전 선택표
문제가 보일 때 | 먼저 볼 패턴 |
|---|---|
상속 계층이 깊어진다 | |
정책이나 알고리즘이 자주 바뀐다 | |
외부 SDK 모양이 내부 코드에 퍼진다 | |
하위 시스템 호출 순서가 복잡하다 | |
부가 기능을 원래 객체 수정 없이 붙이고 싶다 | |
중첩 | |
실패를 호출자가 직접 처리해야 한다 | |
상태별 행동과 전이가 복잡하다 | |
한 객체의 변화를 여러 수신자에게 알려야 한다 | |
도메인 코드에 DB 세부사항이 새어 나온다 | |
여러 저장 작업 가운데 일부만 반영된다 | |
화면 조회가 도메인 모델을 억지로 끌고 온다 | |
외부 호출이 가끔 실패한다 | |
외부 의존성 장애가 내 시스템까지 죽인다 | |
느린 의존성 하나가 다른 호출의 자원까지 다 쓴다 | |
특정 클라이언트의 요청이 서버를 압도한다 | |
같은 데이터를 반복해서 읽는다 | |
화면의 입력 처리, 표시, 규칙이 한 클래스에 뒤엉킨다 |
- 문제가 보일 때
상속 계층이 깊어진다
- 먼저 볼 패턴
- 문제가 보일 때
정책이나 알고리즘이 자주 바뀐다
- 먼저 볼 패턴
- 문제가 보일 때
외부 SDK 모양이 내부 코드에 퍼진다
- 먼저 볼 패턴
- 문제가 보일 때
하위 시스템 호출 순서가 복잡하다
- 먼저 볼 패턴
- 문제가 보일 때
부가 기능을 원래 객체 수정 없이 붙이고 싶다
- 먼저 볼 패턴
- 문제가 보일 때
중첩
if가 깊어진다- 먼저 볼 패턴
- 문제가 보일 때
실패를 호출자가 직접 처리해야 한다
- 먼저 볼 패턴
- 문제가 보일 때
상태별 행동과 전이가 복잡하다
- 먼저 볼 패턴
- 문제가 보일 때
한 객체의 변화를 여러 수신자에게 알려야 한다
- 먼저 볼 패턴
- 문제가 보일 때
도메인 코드에 DB 세부사항이 새어 나온다
- 먼저 볼 패턴
- 문제가 보일 때
여러 저장 작업 가운데 일부만 반영된다
- 먼저 볼 패턴
- 문제가 보일 때
화면 조회가 도메인 모델을 억지로 끌고 온다
- 먼저 볼 패턴
- 문제가 보일 때
외부 호출이 가끔 실패한다
- 문제가 보일 때
외부 의존성 장애가 내 시스템까지 죽인다
- 먼저 볼 패턴
- 문제가 보일 때
느린 의존성 하나가 다른 호출의 자원까지 다 쓴다
- 먼저 볼 패턴
- 문제가 보일 때
특정 클라이언트의 요청이 서버를 압도한다
- 먼저 볼 패턴
- 문제가 보일 때
같은 데이터를 반복해서 읽는다
- 먼저 볼 패턴
- 문제가 보일 때
화면의 입력 처리, 표시, 규칙이 한 클래스에 뒤엉킨다
- 먼저 볼 패턴
패턴 남용 신호
변형이 하나뿐인데 Strategy를 만든다.
외부 시스템이 하나뿐인데 Adapter 계층을 여러 겹 만든다.
단순 함수 호출을 Command 객체로 감싼다.
전이 함수로 충분히 읽히는데 상태마다 클래스를 만든다.
CRUD 화면에 DDD, CQRS, Event Sourcing을 다 얹는다.
이름은 패턴인데 실제로는 책임을 숨기는 거대한 객체가 된다.
교과서적으로 말하자면 패턴은 실력 자랑용 장식이 아니다.
지금 코드가 실제로 겪는 변경 압력을 줄일 때만 의미있다.
개인 메모: 다만 프로그램 코드 설명할때 패턴으로 말하면, 멋있어 보이고 의뢰인이 돈을 더 잘 쳐주는 경향이 있다. 별 건 아니더라도 전문성처럼 보일때가 있다. 교과서적으로는 허세용이 아니다라고 하지만, 모든게 교과서대로는 아닌것이다.
같이 보기
SQL
컬럼형 데이터베이스
참고문헌
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
Joshua Kerievsky. Refactoring to Patterns. Addison-Wesley, 2004.
https://www.informit.com/store/refactoring-to-patterns-9780321213358
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
Vaughn Vernon. Implementing Domain-Driven Design. Addison-Wesley, 2013.
https://books.google.com/books/about/Implementing_Domain_Driven_Design.html?id=X7DpD5g3VP8C
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
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/
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/
Martin Kleppmann. Designing Data-Intensive Applications. O’Reilly, 2017.
https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/
Chris Richardson. Microservices Patterns: With Examples in Java. Manning, 2018.
https://www.manning.com/books/microservices-patterns
https://microservices.io/patterns/
Mark Seemann, Steven van Deursen. Dependency Injection Principles, Practices, and Patterns. Manning, 2019.
https://www.manning.com/books/dependency-injection-principles-practices-patterns
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
John Ousterhout. A Philosophy of Software Design. Yaknyam Press, 2018.
https://web.stanford.edu/~ouster/cgi-bin/aposd2ndEdExtract.pdf
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
Microsoft Azure Architecture Center. Cloud Design Patterns.
https://learn.microsoft.com/en-us/azure/architecture/patterns/
분류: 프로그래밍 | 소프트웨어 공학 | 디자인 패턴 | WIKI
각주
- 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 ↩
- Martin Fowler. Patterns of Enterprise Application Architecture. Addison-Wesley, 2002. https://martinfowler.com/books/eaa.html ↩
- Release It! 2판 출판사 목차 · Microsoft Cache-Aside 패턴. ↩