디자인 패턴별로 특징 장단점 그리고 대표적인 사용 사례를 간단하게 정리했습니다.
- 특징: 클래스 인스턴스를 단 하나만 만들도록 제한함
- 장점: 메모리 절약 효과가 있고 어디에서든 하나의 인스턴스를 접근할 수 있음
- 단점: 전역 상태로 인해 테스트가 어려워질 수 있고 멀티스레드 환경에서는 주의가 필요함
- 사용 사례: 로거 데이터베이스 연결 객체 설정 관리
- 코드 보기
- 특징: 객체 생성 과정을 별도의 클래스로 분리
- 장점: 객체 생성과 사용이 명확하게 분리되어 확장이나 변경이 쉬움
- 단점: 클래스가 많아지고 구조가 복잡해질 수 있음
- 사용 사례: 여러 타입의 객체가 필요한 상황
- 코드 보기
- 특징: 관련 있는 객체 묶음을 한 번에 생성하는 팩토리
- 장점: 제품군 단위로 일관성 있게 객체를 만들 수 있고 교체도 쉬움
- 단점: 새로운 제품을 추가할 때 모든 팩토리를 수정해야 해서 번거로움
- 사용 사례: UI 라이브러리 데이터베이스 드라이버 등
- 코드 보기
- 특징: 복잡한 객체를 여러 단계에 걸쳐 생성
- 장점: 가독성이 좋고 옵션이 많은 객체 생성에 유용함
- 단점: 코드가 길어질 수 있고 단순한 객체에는 오히려 번거로울 수 있음
- 사용 사례: SQL 쿼리 빌드 HTTP 요청 작성 등
- 코드 보기
- 특징: 기존 객체를 복제해서 새로운 객체를 만듦
- 장점: 생성 비용이 큰 객체를 효율적으로 복제 가능
- 단점: 복잡한 객체는 깊은 복사가 까다로울 수 있음
- 사용 사례: 게임 오브젝트 복사 문서 템플릿 등
- 코드 보기
- 특징: 맞지 않는 인터페이스끼리 연결
- 장점: 기존 코드를 쉽게 재활용하고 인터페이스를 하나로 맞출 수 있음
- 단점: 설계가 복잡해질 수 있고 약간의 성능 저하가 있을 수 있음
- 사용 사례: 레거시 코드 연동 외부 라이브러리 감싸기
- 코드 보기
- 특징: 추상화와 구현을 분리해 독립적으로 확장
- 장점: 각 부분을 따로 확장할 수 있고 실행 중에 구현을 바꿀 수 있음
- 단점: 구조가 복잡해지고 필요 이상으로 추상화가 될 가능성도 있음
- 사용 사례: GUI 프레임워크 드라이버 시스템
- 코드 보기
- 특징: 개별 객체와 복합 객체를 동일하게 다룸
- 장점: 트리 구조처럼 계층적인 구조 관리에 적합하고 일관된 인터페이스 제공
- 단점: 타입 안전성이 약해질 수 있고 너무 일반화될 위험이 있음
- 사용 사례: 파일 시스템 UI 컴포넌트 구성
- 코드 보기
- 특징: 객체에 새로운 기능을 동적으로 추가
- 장점: 상속 없이 기능 확장이 가능하고 실행 중에 기능을 바꿀 수 있음
- 단점: 작은 객체가 너무 많아질 수 있고 디버깅이 복잡해질 수 있음
- 사용 사례: 스트림 처리 미들웨어 GUI 컴포넌트 등
- 코드 보기
- 특징: 복잡한 시스템을 간단한 인터페이스로 감싸서 제공
- 장점: 사용이 쉬워지고 내부 구조 변경에 덜 민감해짐
- 단점: 인터페이스에서 모든 기능을 지원하지 못할 수 있고 내부 시스템이 바뀌면 파사드도 수정이 필요함
- 사용 사례: API 래퍼 복잡한 라이브러리 인터페이스 정리 등
- 코드 보기
- 특징: 공통된 데이터를 공유해 메모리 사용을 줄임
- 장점: 메모리 절약 효과가 크고 성능이 향상될 수 있음
- 단점: 코드가 복잡해지고 공유하지 않는 속성 관리가 까다로움
- 사용 사례: 텍스트 에디터 게임 엔진의 오브젝트 관리
- 코드 보기
- 특징: 실제 객체에 대한 접근을 제어
- 장점: 지연 로딩 접근 권한 관리 캐싱 등 다양한 용도에 활용
- 단점: 응답 시간이 길어질 수 있고 구조가 더 복잡해짐
- 사용 사례: 가상 프록시 보안 프록시 원격 프록시 등
- 코드 보기
- 특징: 요청을 처리할 수 있는 여러 객체를 체인 형태로 연하여 관리 가능
- 장점: 요청을 보내는 쪽과 처리하는 쪽을 분리할 수 있고 체인을 동적으로 구성할 수 있음
- 단점: 요청이 꼭 처리된다는 보장이 없으며 어디에서 처리됐는지 파악하거나 디버깅이 어려움
- 사용 예시: 이벤트 처리 예외 처리 미들웨어 구현 등에 자주 활용됨
- 코드 보기
- 특징: 요청 내용을 하나의 객체로 캡슐화해 저장하거나 전달 실행 시점 변경 등을 쉽게 관리
- 장점: 요청을 큐에 쌓아두거나 실행 취소와 같은 기능이나 로깅을 구현 할 수 있음
- 단점: 관련 클래스가 많아져 구조가 복잡해지고 메모리도 더 사용할 수 있음
- 사용 예시: GUI 버튼 이벤트 매크로 기능 트랜잭션 관리 등에서 활용됨
- 코드 보기
- 특징: 컬렉션 내부 구조와 상관없이 요소를 순차적으로 접근할 수 있는 방법을 제공
- 장점: 컬렉션 구조와 순회 방식이 분리되고 통일된 인터페이스로 다양하게 구현 가능함
- 단점: 간단한 컬렉션의 경우 오히려 복잡할 수 있고 성능 면에서 추가 오버헤드 발생 가능
- 사용 예시: 배열이나 리스트 등 컬렉션 순회 데이터베이스 결과 처리 시 주로 사용
- 코드 보기
- 특징: 여러 객체 사이의 상호작용을 중재하는 별도의 객체를 둬 직접 연결을 줄임
- 장점: 객체 간의 결합도가 낮아지고 통신 관련 로직을 중앙에서 관리하여 낮은 결합도를 가짐
- 단점: 중재자 역할을 하는 객체가 복잡해질 수 있고 전체 시스템이 그 객체에 의존하는 문제가 발생할 수 있음
- 사용 예시: 채팅 시스템 GUI 컴포넌트 관리 이벤트 시스템 등에서 자주 쓰임
- 코드 보기
- 특징: 객체의 특정 시점 상태를 저장했다가 필요할 때 복원이 가능함
- 장점: 상태 저장과 복구가 가능해 실행 취소 기능을 쉽게 구현할 수 있음
- 단점: 상태 정보를 많이 저장하면 메모리 사용이 커지고 내부 상태가 외부에 노출될 위험이 있음
- 사용 예시: 에디터의 실행 취소 게임 저장 트랜잭션 롤백 등에 활용
- 코드 보기
- 특징: 한 객체의 상태 변화가 발생했을 때 여러 관찰자에게 자동으로 알릴 수 있음
- 장점: 느슨한 결합 구조를 만들 수 있고 구독과 해지를 동적으로 처리
- 단점: 관찰자가 많아지면 메모리 누수가 발생할 수 있고 알림 순서나 결과를 예측하기 어려움
- 사용 예시: 이벤트 시스템 MVC 구조 리액티브 프로그래밍 등
- 코드 보기
- 특징: 객체의 현재 상태에 따라 동작이 달라지도록 구현
- 장점: 각 상태별로 로직이 명확히 분리되고 상태 전환 또한 쉽게 관리
- 단점: 상태마다 클래스를 따로 두면 클래스 수가 늘어나고 전환 과정이 복잡해질 수 있음
- 사용 예시: 게임 속 캐릭터 주문 상태 처리 자동판매기 프로그램 등에 활용
- 코드 보기
- 특징: 알고리즘 각각을 클래스로 만들어 상황에 따라 자유롭게 교체
- 장점: 알고리즘 변경이 간편하고 복잡한 조건문 없이 다양한 방식의 처리가 가능
- 단점: 사용할 전략마다 클래스를 따로 만들어야 하니 구조가 커질 수 있고 어떤 전략을 쓸지는 클라이언트가 직접 정해야 함
- 사용 예시: 정렬 방법 결제 수단 파일 압축 알고리즘 선택 등에 유용하게 쓰임
- 코드 보기
- 특징: 다른 일련의 알고리즘을 추가하고자 할 때 작동하는 객체로부터 분리
- 장점: 개방 폐쇄 원칙을 준수하며 만약 작동하는 객체에 추가 할 때 버그 리스크가 있지만 분리하여 구현하면 문제 없이 처리 가능
- 단점: 클래스에 요소가 추가되거나 변경사항이 있을 시에 일일히 수정해야 하는 번거로움이 있음
- 사용 예시: 복잡하게 작동하는 모놀리스 아키텍처 등에 사용 (더 이상 코드를 복잡하게 만들고 싶지 않을 때)
- 코드 보기
- 특징: 부모 객체를 상속하여 특정 단계를 오버라이딩 하는 패턴
- 장점: 알고리즘의 특정 부분만 영향을 받게 하여 변경에 영향을 덜 받게 할 수 있음
- 단점: 많을수록 유지가 어려우며 리스코프 치환 원칙에 위배될 수 있음
- 사용 예시: 구글 인증 프로바이더, 깃허브 인증 프로바이더 등 책임이 같지만 로직이 다른 경우에 유용하게 쓰임
- 코드 보기





















