디자인 패턴
Design Pattern
방법
코드를 짜다 되풀이해 만나는 설계 문제마다 검증된 해법의 뼈대에 이름을 붙여 둔 목록입니다.
등장 배경
같은 문제가 회사마다 다시 풀리던 시절이 있었습니다. 설정값 하나를 프로그램 전체에서 하나만 두고 싶다거나, 계산 방식을 나중에 갈아 끼울 수 있게 해 두고 싶다거나, 무언가 바뀌었을 때 그 사실을 여러 곳에 알려야 한다거나 하는 문제입니다. 누구나 만나는 문제인데 부를 이름이 없었습니다.
그래서 코드 리뷰가 유독 길어졌습니다. 코드 리뷰는 합치기 전에 동료가 코드를 읽어 보는 절차인데, 이름이 없으면 매번 처음부터 설명해야 합니다. "여기를 이렇게 나눠 두면 나중에 계산 방식이 하나 더 생겨도 이 파일만 고치면 됩니다" 를 그림까지 그려 가며 20분 설명하고, 듣는 쪽은 그게 좋은 방식인지 그냥 그 사람 취향인지 판단할 근거가 없습니다.
1994년에 나온 책 한 권이 이런 문제 스물세 가지에 이름과 해법을 붙이면서 상황이 바뀌었습니다. 같은 것을 부르는 말이 생기자 20분짜리 설명이 한 단어로 줄었습니다.
소프트웨어 아키텍처 아래에서 디자인 패턴은 설계 지식 갈래에 속합니다. 앞사람들이 겪고 정리해 둔 것을 꺼내 쓰게 해 주는 자리라, 매번 처음부터 고민하지 않게 하는 것이 이 갈래가 하는 일입니다.
사용 절차
패턴은 먼저 고르는 것이 아니라 문제를 만난 뒤에 꺼내는 것입니다. 순서는 다섯 칸입니다.
- 지금 걸린 문제를 한 문장으로 적습니다. "알림을 보내는 코드가 문서 저장 코드 안에 들어가 있어서 알림 하나를 더할 때마다 저장 코드를 고쳐야 한다" 처럼 씁니다. 이 문장이 안 써지면 아직 패턴을 찾을 단계가 아닙니다.
- 그 문장과 같은 모양의 문제에 이름이 붙어 있는지 찾습니다. 하나만 두고 싶은 문제는 싱글턴, 여러 방식 중 하나를 골라 갈아 끼우고 싶은 문제는 전략 패턴, 무언가 바뀌었을 때 관심 있는 쪽들이 알아서 받아 가게 하고 싶은 문제는 옵저버 패턴입니다.
- 해법을 그대로 베끼지 않고 뼈대만 가져옵니다. 패턴은 붙여 넣을 코드가 아니라 어떤 조각을 두고 누가 누구를 부르게 할지에 대한 배치도입니다.
- 팀에서 그 이름을 부릅니다. 코드에 주석 한 줄이나 파일 이름으로 남겨 두면 다음 사람이 새 계산 방식을 어디에 끼워야 하는지 물어보지 않고 압니다. 이름을 안 부르면 3번까지 한 일이 그 사람 혼자 아는 구조로 남습니다.
- 안 맞으면 버립니다. 넣어 보고 코드가 오히려 읽기 어려워졌으면 되돌립니다. 이름이 붙어 있다는 사실이 그 자리에 맞는다는 보증은 아닙니다.
페이지덱에서 문서 저장이 이 순서를 그대로 거쳤습니다. 저장될 때마다 알림을 보내고 검색 색인을 갱신하고 활동 기록을 남겨야 하는데, 셋이 다 저장 코드 안에 들어가 있었습니다. 태오가 이것을 옵저버 패턴으로 바꿨습니다. 저장 쪽은 "문서가 저장됐다" 는 사실만 알리고 알림과 색인과 기록은 각자 그 사실을 받아 갑니다. 그다음 분기에 기능이 하나 더 붙었을 때 저장 코드는 한 줄도 바뀌지 않았습니다.
적합한 상황과 한계
같은 모양의 문제가 세 번째 나왔을 때가 꺼낼 때입니다. 처음 나왔을 때는 그냥 풀고, 두 번째에는 비슷하다는 것만 기억해 두고, 세 번째에 패턴으로 묶습니다. 첫 번째부터 패턴을 씌우면 아직 어느 방향으로 늘어날지 모르는 채로 구조를 굳히게 됩니다.
한계는 셋입니다. 첫째, 패턴을 먼저 정해 놓고 문제를 거기에 맞추는 경우입니다. 이렇게 하면 함수 하나로 끝날 일에 인터페이스와 클래스 다섯 개가 생기고, 응집도는 그대로인데 읽을 파일만 늘어납니다. 둘째, 언어가 이미 해결한 것을 굳이 패턴으로 만드는 경우입니다. 함수를 값처럼 넘길 수 있는 언어에서 전략 패턴은 함수 하나를 인자로 받는 것으로 끝나고, 거기에 클래스 구조를 세우면 남는 것은 이름뿐입니다. 셋째, 이름이 뜻을 대신하는 경우입니다. 패턴 이름이 붙으면 검토가 느슨해져 정작 결합도가 높아졌는지는 아무도 보지 않습니다.
쓰기 좋은 자리는 반대로 분명합니다. 나중에 종류가 늘어날 것이 확실한 곳, 여러 사람이 같은 파일을 만지는 곳, 그리고 이미 리팩터링을 하기로 정한 곳입니다. 리팩터링은 동작은 그대로 두고 구조만 고치는 작업이라, 패턴은 그 작업의 도착점을 정해 주는 역할을 합니다.
실무 용례
"이건 옵저버로 가죠. 저장될 때마다 알림이랑 색인이 같이 따라가야 해요."
저장 쪽과 알림 쪽을 떼어 놓자는 제안이고, 이름 하나로 배치까지 합의된 상태입니다.
"패턴 이름은 붙었는데 클래스가 다섯 개 늘었네요. 함수 하나면 안 되나요?"
구조를 세운 값어치가 문제 크기에 비해 크다는 지적입니다.
"전략 패턴이라고 적어 두면 다음 사람이 새 계산 방식을 어디에 넣을지 바로 압니다."
패턴의 쓸모가 코드 자체보다 다음 사람에게 전해지는 데 있다는 말입니다.
페이지덱에서 이 말이 가장 자주 오가는 자리는 코드 리뷰입니다. 태오가 올린 변경에 누군가 "여기 팩토리로 빼는 게 낫지 않아요" 라고 달면, 그 한 줄로 어떤 조각이 어디로 옮겨 가는지가 서로에게 그려집니다. 이름이 없던 시절이라면 같은 제안에 댓글 열 줄이 필요했습니다.
반대로 이름이 대화를 끝내 버리는 경우도 봅니다. 리뷰에서 "이거 싱글턴이에요" 라는 답이 나오면 대개 더 묻지 않는데, 정작 물어야 할 것은 프로그램 전체에서 하나만 두는 게 맞느냐입니다. 테스트할 때 그 하나를 가짜로 바꿔치기할 수 없어 단위 테스트가 통째로 막히는 일이 여기서 나옵니다.
흔한 오해
패턴을 많이 쓸수록 좋은 설계라는 오해가 가장 흔합니다. 이름을 아는 만큼 실력이 보이는 것처럼 느껴지고, 면접에서도 이름을 묻는 경우가 많아서 그렇게 굳기 쉽습니다. 하지만 패턴은 복잡한 문제를 다루는 값으로 복잡한 구조를 지불하는 거래입니다. 문제가 단순한데 값만 치르면 남는 것은 빚입니다. 한 줄을 바꾸려고 파일 다섯 개를 따라 들어가야 하고, 새로 들어온 사람은 그 구조가 무슨 문제를 푸는지 아무도 설명해 주지 못하는 상태를 만납니다.
이름 때문에 생기는 오해도 있습니다. 디자인 패턴을 화면 디자인 이야기로 아는 경우입니다. 같은 말이 UI 쪽에도 쓰여서 헷갈리기 쉽지만, 이 말의 디자인은 시각 디자인이 아니라 설계를 뜻합니다. 화면에서 되풀이되는 배치를 가리킬 때는 UI 패턴이라고 따로 부릅니다. 이 둘을 섞어 두면 개발자와 디자이너가 같은 단어로 다른 것을 이야기하면서 회의가 한참 헛돕니다.
자주 헷갈리는 용어
| 용어 | 다루는 크기 | 디자인 패턴과의 차이 |
|---|---|---|
| 소프트웨어 아키텍처 | 시스템 전체를 어떤 덩어리로 나누고 어떻게 이을지 | 배포 단위와 층을 정하는 큰 결정이라 한 번 정하면 바꾸는 값이 큽니다. 디자인 패턴은 그 덩어리 안쪽 코드의 배치라서 한 파일 범위에서 넣었다 뺐다 할 수 있습니다 |
같이 보면 좋은 페이지
- 소프트웨어 아키텍처
패턴이 어느 층위의 결정 아래에 놓이는지 먼저 봅니다
- SOLID 원칙
패턴이 따르는 다섯 가지 설계 규칙을 확인합니다
마지막 업데이트 2026-09-16