Software Design

디자인 패턴 왜 필요할까, 그리고 왜 맹신하면 안 될까 (실무 기준 정리)

"디자인 패턴, 요즘도 공부해야 하나요?"라는 질문을 개발 커뮤니티에서 심심찮게 볼 수 있습니다.

이석우iOS Developer6분 읽기
디자인 패턴 왜 필요할까, 그리고 왜 맹신하면 안 될까 (실무 기준 정리) 대표 이미지

“디자인 패턴, 요즘도 공부해야 하나요?“라는 질문을 개발 커뮤니티에서 심심찮게 볼 수 있습니다.

한쪽에서는 “기본기니까 무조건 익혀라”라고 하고, 다른 쪽에서는 “요즘 언어에서는 절반이 필요 없다”라고 합니다. 둘 다 일리가 있으니 더 헷갈립니다.

결론부터 말씀드리면, 디자인 패턴은 배울 가치가 충분합니다. 다만 “패턴을 적용하는 것” 자체가 목적이 되는 순간부터는 오히려 코드를 망치는 지름길이 됩니다.

이 글에서는 디자인 패턴이 왜 필요한지, 또 왜 맹신하면 안 되는지 순서대로 짚어 보겠습니다.

디자인 패턴의 두 얼굴을 담은 대표 이미지 — 청사진 스타일 UML 다이어그램과 나사를 내리치는 골든 해머
왼쪽의 설계도와 오른쪽의 골든 해머, 이 글에서 다룰 디자인 패턴의 두 얼굴입니다

디자인 패턴이 뭐길래

디자인 패턴은 한마디로 자주 반복되는 설계 문제를 푸는 검증된 해법의 목록입니다.

1994년 GoF(Gang of Four)가 『Design Patterns』라는 책에서 23개의 패턴을 정리한 게 출발점이에요. 싱글톤, 팩토리, 옵저버, 전략 패턴 같은 이름들이 전부 여기서 나왔습니다.

중요한 건, 이 패턴들이 누군가 책상에서 발명한 게 아니라는 점입니다. 수많은 프로젝트에서 개발자들이 비슷한 문제를 비슷한 방식으로 풀고 있다는 걸 관찰하고, 거기에 이름을 붙여 카탈로그로 만든 것이에요.

그래서 디자인 패턴의 본질은 “새로운 기술”이 아니라 “정리된 경험”에 가깝습니다.


왜 필요한가 1 — 팀의 공용 어휘

디자인 패턴의 가장 큰 실용적 가치는 코드가 아니라 커뮤니케이션에 있습니다.

“이 클래스는 인스턴스를 하나만 유지하고, 전역에서 접근할 수 있게 하고, 초기화 시점은 첫 접근 때로 미루자”라고 설명하는 대신 “싱글톤으로 갑시다” 한마디면 끝납니다.

코드 리뷰에서 “여기 옵저버 패턴이 낫지 않을까요?“라는 코멘트 하나에 얼마나 많은 정보가 담기는지 생각해 보면, 패턴 이름은 압축률이 굉장히 높은 언어입니다.

이 어휘를 모르면 팀 대화와 기술 문서, 오픈소스 코드 주석을 읽는 속도가 전부 느려집니다. 기술 면접에서 디자인 패턴을 계속 묻는 이유도 여기에 있어요.


왜 필요한가 2 — 프레임워크를 읽는 열쇠

우리가 매일 쓰는 프레임워크가 이미 디자인 패턴 덩어리입니다.

  • iOS의 UITableViewDelegate델리게이트 패턴
  • NotificationCenter와 Combine의 publisher는 옵저버 패턴
  • SwiftUI의 View 프로토콜 조합은 컴포지트 패턴에 가깝고
  • URLSession.shared싱글톤입니다

패턴을 알면 프레임워크 API를 처음 봐도 “아, 이건 이 구조겠구나” 하고 설계 의도를 역으로 읽을 수 있습니다. 문서를 읽는 시간이 줄어드는 게 아니라, 문서에 없는 부분까지 예측하게 됩니다.

델리게이트·옵저버·싱글톤·팩토리·전략 디자인 패턴 블록으로 조립된 iOS 앱 화면 일러스트
델리게이트, 옵저버, 싱글톤… 매일 쓰는 프레임워크가 이미 패턴 조립품이에요

왜 필요한가 3 — 검증된 해법의 재사용

같은 문제를 처음부터 고민하며 푸는 것과, 수십 년간 다듬어진 해법에서 출발하는 것은 출발선이 다릅니다.

예를 들어 “객체 생성 로직이 여기저기 흩어져서 수정할 때마다 빠뜨린다”는 문제는 팩토리 패턴이, “상태가 바뀔 때마다 여러 화면을 갱신해야 한다”는 문제는 옵저버 패턴이 이미 다뤄 본 문제입니다.

패턴에는 해법만 있는 게 아니라 그 해법의 트레이드오프까지 정리되어 있습니다. “싱글톤은 전역 상태라서 테스트가 어려워진다” 같은 부작용 목록까지가 패턴의 일부예요. 선배들이 밟은 지뢰의 위치가 지도에 표시되어 있는 셈입니다.


그런데 왜 맹신하면 안 될까

여기까지만 보면 디자인 패턴은 만능처럼 보입니다. 문제는 패턴을 “알게 된 직후”에 자주 벌어집니다.

망치를 들면 모든 게 못으로 보인다

패턴을 배우고 나면 어디든 적용하고 싶어지는데, 이게 유명한 골든 해머(golden hammer) 함정입니다.

설정값 하나 읽는 코드에 추상 팩토리를 씌우고, 분기 두 개짜리 로직에 전략 패턴을 도입하고, 클래스 하나면 될 일을 인터페이스 3개와 구현체 4개로 쪼개는 식이죠.

패턴은 복잡성을 줄이려고 쓰는 도구인데, 문제가 충분히 복잡하지 않은 곳에 쓰면 패턴 자체가 새로운 복잡성이 됩니다. 코드를 처음 보는 사람이 실제 로직을 찾으려고 파일 6개를 건너뛰어야 한다면, 그건 설계가 아니라 미로입니다.

언어가 발전하면 패턴은 사라진다

GoF의 23개 패턴은 1994년의 C++와 Smalltalk를 전제로 정리된 것입니다. 그중 상당수는 언어 기능이 흡수해 버렸어요.

// 1994년식: 전략 패턴 — 프로토콜 + 구현체 클래스들
protocol SortStrategy {
    func sort(_ numbers: [Int]) -> [Int]
}
final class AscendingSort: SortStrategy {
    func sort(_ numbers: [Int]) -> [Int] { numbers.sorted(by: <) }
}

// 요즘 Swift: 클로저 하나면 같은 목적 달성
let sorted = numbers.sorted(by: >)

함수를 값처럼 넘길 수 있는 언어에서는 전략·커맨드 패턴 대부분이 클로저 한 줄로 끝납니다. Swift의 enum과 값 타입, 프로토콜 기본 구현도 과거에는 패턴으로 풀던 문제를 문법 차원에서 해결하죠.

패턴은 “언어가 아직 못 해주는 일을 사람이 구조로 메꾼 것”이라는 관점도 있습니다. 그러니 패턴 목록을 시대 불변의 정답으로 외우면, 언어가 이미 해결한 문제를 수십 년 전 방식으로 푸는 코드가 나옵니다.

패턴이 목적이 되는 순간

가장 위험한 신호는 설계 논의가 “이 문제를 어떻게 풀까”가 아니라 “어떤 패턴을 쓸까”에서 출발하는 것입니다.

패턴은 문제를 풀다 보니 도달하는 종착지에 가깝지, 출발점이 아닙니다. 실제로 리팩터링 문헌들은 “처음부터 패턴을 깔지 말고, 코드가 그 방향의 압력을 받을 때 패턴 쪽으로 리팩터링하라”고 조언합니다.

디자인 패턴 적용 판단 플로차트 — 문제의 반복성과 트레이드오프를 검토해 단순 유지 또는 패턴 리팩터링을 선택
패턴은 출발점이 아니라, 압력이 생겼을 때 도달하는 종착지에 가깝습니다

그래서 어떻게 쓰면 좋을까

정리하면 균형점은 이렇습니다.

배울 때는 해법보다 문제를 먼저 보세요. 각 패턴이 “어떤 상황에서” 등장했는지를 기억해야, 그 상황이 아닐 때 안 쓸 수 있습니다. 패턴 공부의 절반은 “언제 쓰지 말아야 하는가”입니다.

적용할 때는 가장 단순한 코드에서 출발하세요. 중복이 세 번 생기고, 변경 요구가 실제로 들어오고, 지금 구조가 버거워질 때 — 그때 패턴으로 리팩터링해도 늦지 않습니다. 미래의 유연성을 위해 오늘 복잡성을 사는 건 대부분 손해 보는 거래입니다.

읽을 때는 적극적으로 활용하세요. 남의 코드, 프레임워크, 오픈소스를 읽을 때 패턴 지식은 부작용 없는 순수한 이득입니다. 맹신의 위험은 “쓸 때” 생기지 “읽을 때” 생기지 않으니까요.


정리

  • 디자인 패턴은 반복되는 설계 문제를 푸는 검증된 해법의 카탈로그로, 발명이 아니라 관찰의 산물입니다.
  • 필요한 이유: 팀의 공용 어휘, 프레임워크 설계를 읽는 열쇠, 트레이드오프까지 정리된 검증된 해법.
  • 맹신하면 안 되는 이유: 단순한 문제에 씌우면 패턴 자체가 복잡성이 되고(골든 해머), 언어 발전으로 사라지는 패턴도 많으며, 패턴이 목적이 되면 설계가 뒤집힙니다.
  • 실무 기준: 문제에서 출발해 단순한 코드로 시작하고, 압력이 생길 때 패턴으로 리팩터링. 읽기 용도로는 아낌없이 활용.

함께 보면 좋은 글