Computer Science/Design Pattern
디자인 패턴 총정리
guwon2
2025. 10. 1. 15:51
디자인 패턴
싱글톤 패턴 (Singleton Pattern)
하나의 클래스에 오직 하나의 인스턴스만 생성하도록 보장하는 패턴
장점
- 인스턴스 생성 비용 절약: 메모리 효율성 향상
- 전역 접근: 애플리케이션 전체에서 동일한 인스턴스 사용
- 지연 초기화: 필요한 시점에만 인스턴스 생성
단점
- 의존성 증가: 전역 상태로 인한 결합도 상승
- TDD 어려움: 테스트 간 독립성 훼손 (테스트는 서로 독립적이고 순서에 상관없어야 함)
- 멀티스레딩 이슈: Thread-Safe 구현 필요
사용 사례
- 데이터베이스 연결 모듈
- 커넥션 풀
- 스레드 풀
- 설정 객체
구현 방법
// Thread-Safe한 싱글톤 (권장)
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
해결책: 의존성 주입을 통해 테스트 용이성 개선 가능
팩토리 패턴 (Factory Pattern)
객체 생성 부분을 분리하여 추상화한 패턴
- 상위 클래스: 뼈대 결정
- 하위 클래스: 구체적인 객체 생성 내용 결정
장점
- 느슨한 결합 → 유연성 증가
- 유지보수성 향상
- 단일 책임 원칙 준수
- 개방/폐쇄 원칙 준수
- 캡슐화/추상화 실현
단점
- 코드 복잡성 증가
- 서브클래스 수 증가
실제 사용 예시
NumberFormat.getInstance()(Java)Calendar.getInstance()(Java)BeanFactory(Spring Framework)
전략 패턴 (Strategy Pattern, Policy Pattern)
개념
객체의 행위를 직접 수정하지 않고, 캡슐화된 알고리즘을 컨텍스트에서 교체하여 상호 교환 가능하게 만드는 패턴
장점
- OOP 기술의 총집합: OCP, DIP, 합성, 다형성, 캡슐화 모두 활용
- 런타임 알고리즘 변경 가능
- 테스트 용이성 향상
단점
- 알고리즘 증가 → 관리해야 할 객체 수 증가
실제 사용 예시
Collections.sort()의ComparatorHttpServlet의doXXX()메서드들Filter의doFilter()메서드- Spring의
BeanDefinitionParser,PlatformTransactionManager,CacheManager - 결제 방식 선택 로직
옵저버 패턴 (Observer Pattern)
주체 객체의 상태 변화를 관찰하다가 변화가 있을 때마다 등록된 옵저버들에게 자동으로 알림을 전달하는 패턴
장점
- 실시간 감지: 주기적 폴링 없이 상태 변화 자동 감지
- 확장성: 새로운 옵저버 추가 시 기존 코드 수정 불필요
- 느슨한 결합: Subject와 Observer 간 독립성
단점
- 알림 순서 제어 불가
- 메모리 누수 위험: 옵저버 해지하지 않을 경우
사용 사례
- SNS 알림 (트위터, 페이스북)
- 이벤트 기반 시스템
- MVC 패턴의 Model-View 관계
Java 구현 방법
java.lang.reflect.Proxy사용java.util.Observable,java.util.Observer활용
프록시 패턴 (Proxy Pattern)
대상 객체에 접근하기 전, 접근 흐름을 가로채서 대상 객체 앞단에서 인터페이스 역할을 수행하는 패턴
주요 사용 목적
- 보안: 접근 권한 제어
- 데이터 검증: 입력값 검증
- 캐싱: 결과 캐싱으로 성능 향상
- 로깅: 요청/응답 로깅
프록시 서버 활용
서버-클라이언트 사이에서 간접 접속을 가능하게 하는 시스템
대표적인 프록시 서버: Nginx
- 버퍼 오버플로우 예방
- CDN (CloudFlare): 캐싱
- DDoS 방어
- HTTPS 구축
- CORS 문제 해결
이터레이터 패턴 (Iterator Pattern)
다양한 자료구조를 하나의 통일된 인터페이스로 순회할 수 있게 해주는 패턴
장점
- 일관된 순회 방법: ArrayList, LinkedList, HashSet 등 모두 동일한 방식으로 접근
- 내부 구조 은닉: 컬렉션 내부 구현에 의존하지 않음
노출모듈 패턴 (Revealing Module Pattern)
즉시 실행 함수(IIFE)를 통해 private, public 같은 접근 제어자를 구현하는 패턴
JavaScript 예시
const myModule = (function() {
let privateVar = 0;
function privateFunction() {
console.log('Private function');
}
return {
publicMethod: function() {
privateVar++;
privateFunction();
},
getCount: function() {
return privateVar;
}
};
})();아키텍처 패턴
MVC 패턴 (Model-View-Controller)
구성 요소
- Model: 데이터베이스, 상수, 변수 등 애플리케이션 데이터
- View: 사용자에게 보여지는 UI 요소
- Controller: Model과 View를 연결하는 중재자 역할
- 메인 로직 처리
- 생명주기 관리
장점
- 재사용성: 각 구성 요소의 독립적 재사용
- 확장성: 기능 추가 및 수정 용이
단점
- 복잡성 증가: 애플리케이션이 커질수록 Model-View 관계 복잡화
MVP 패턴 (Model-View-Presenter)
특징
- Controller → Presenter로 변경
- View : Presenter = 1:1 관계
- 더 강한 결합을 가지지만 테스트 용이성 향상
MVVM 패턴 (Model-View-ViewModel)
특징
- Controller → ViewModel로 변경 (View를 더욱 추상화)
- 데이터 바인딩: 자동 UI 업데이트
- 커맨드 패턴: 사용자 액션 처리
장점
- UI 재사용성 향상
- 단위 테스트 용이성
- View와 로직의 완전한 분리
주요 활용 프레임워크
- Vue.js
- Angular
- WPF/Xamarin (Microsoft)
적용
1. 패턴 선택
- 싱글톤: 전역 상태가 정말 필요한 경우만 (설정, 캐시, 연결풀)
- 팩토리: 객체 생성 로직이 복잡하거나 변경 가능성이 높을 때
- 전략: 알고리즘이나 정책이 자주 바뀌는 경우
- 옵저버: 이벤트 기반 시스템, 실시간 알림
- 프록시: 보안, 캐싱, 로깅이 필요한 경우
2. 안티패턴 주의사항
- 과도한 패턴 사용: 단순한 로직에 불필요한 패턴 적용 금지
- 싱글톤 남용: 전역 상태로 인한 테스트 어려움
- 깊은 상속 구조: 합성을 우선 고려
3. 테스트 고려사항
- 의존성 주입: 테스트 더블(Mock, Stub) 활용
- 인터페이스 활용: 구현체 교체 가능한 설계
- 상태 격리: 테스트 간 독립성 보장
출처
- https://ittrue.tistory.com/563
- https://inpa.tistory.com/entry/GOF-💠-팩토리-메서드Factory-Method-패턴-제대로-배워보자
- [https://inpa.tistory.com/entry/GOF-💠-전략Strategy-패턴-제대로-배워보자
디자인 패턴은 도구이다. 문제를 해결하기 위한 수단이지, 그 자체가 목적이 되어서는 안 된다. 항상 "왜 이 패턴을 사용해야 하는가?"를 먼저 생각하고 적용하자!