공부해보잠
디자인 패턴 본문
디자인 패턴 (Design Pattern)의 개요
- 각 모듈의 역할, 모듈 간 인터페이스, 코드 구현 방안을 설계할 때 참조할 수 있는 전형적인 해결 방식 또는 예제이다.
- 문제 해결을 위한 문제 및 배경, 실제 적용 사례, 재사용 가능한 샘플 코드로 구성된다.
- "바퀴를 다시 발명하지 마라(Don’t reinvent the wheel)"라는 원칙처럼, 새롭게 해결책을 구상하는 것보다 기존의 디자인 패턴을 참고하여 적용하는 것이 더욱 효율적이다.
- 한 패턴에 변형을 가하거나 특정 요구사항을 반영하면 유사한 형태의 다른 패턴으로 변화되는 특징이 있다.
디자인 패턴의 역사
- 1995년, **GoF(Gang of Four)**라고 불리는 **에릭 감마(Erich Gamma), 리처드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리시디스(John Vlissides)**가 처음으로 디자인 패턴을 구체화 및 체계화하였다.
- GoF 디자인 패턴은 가장 일반적으로 적용될 수 있는 패턴들을 분류하여 정리하였으며, 현재까지도 소프트웨어 공학 및 현업에서 가장 널리 사용된다.
GoF 디자인 패턴의 유형
유형 | 개수 | 설명 |
생성(Creational) 패턴 | 5개 | 객체의 생성 과정에서의 문제를 해결하는 패턴 |
구조(Structural) 패턴 | 7개 | 클래스나 객체의 구성과 관련된 패턴 |
행위(Behavioral) 패턴 | 11개 | 객체 간의 커뮤니케이션과 관련된 패턴 |
부가설명 :
- 디자인 패턴은 소프트웨어 개발 시 자주 발생하는 문제들을 해결하기 위한 최적의 방법을 제시한다.
- 패턴을 활용하면 코드의 재사용성, 유지보수성, 확장성을 높일 수 있다.
- GoF 패턴은 가장 기본적이고 중요한 디자인 패턴으로, 많은 소프트웨어 개발자가 참고하고 있다.
아키텍처 패턴과 디자인 패턴의 차이
모두 소프트웨어 설계를 위한 참조 모델이지만 다음과 같은 차이가 있습니다.
- 아키택처 패턴은 디자인 패턴보다 상위 수준의 설계에 사용
- 아키택처 패턴이 전체 시스템의 구조를 설계하기 위한 참조모델이라면, 디자인 패턴은 서브시스템에 속하는 컴포넌트들과 그 관계를 설계하기 위한 참조 모델
- 몇몇 디자인 패턴은 특정 아키텍처 패턴을 구현하는데 유용하게 사용
디자인 패턴 사용의 장단점
구분 | 설명 |
장점 | - 범용적인 코딩 스타일을 사용하여 구조 파악이 용이함. |
- 객체지향 설계 및 구현의 생산성을 향상시키는 데 적합. | |
- 검증된 구조의 재사용을 통해 개발 시간과 비용 절감 가능. | |
- 개발자 간의 원활한 의사소통을 지원하여 협업이 용이함. | |
- 설계 변경 요청에 대해 유연하게 대처할 수 있음. | |
단점 | - 초기 투자 비용이 부담될 수 있음 (학습 비용 및 적용 비용). |
- 객체지향을 기반으로 한 설계와 구현을 다루므로 다른 기반의 애플리케이션 개발에는 적합하지 않음. |
부가 설명 :
- 디자인 패턴은 반복적으로 발생하는 문제를 해결하는 일반적인 접근 방식으로, 코드의 유지보수성과 재사용성을 높이는 데 기여한다.
- 하지만 패턴을 과도하게 적용하면 오히려 복잡성이 증가할 수 있으며, 잘못된 사용은 코드의 가독성과 성능을 저하시킬 수도 있다.
- 따라서 상황에 맞는 적절한 패턴을 선택하여 적용하는 것이 중요하다.
생성 패턴(Creational Pattern)
객체의 생성과 관련된 패턴으로, 객체의 생성 및 참조 과정을 캡슐화하여 객체가 생성되거나 변경되더라도 프로그램의 구조에 영향을 최소화하고 유연성을 향상시키는 역할을 한다.
총 5가지 패턴이 있으며, 객체 생성 방식을 조절하여 코드의 결합도를 낮추고 유지보수를 쉽게 만든다.
생성 패턴의 종류 및 특징
패턴명 | 설명 | 특징 |
추상 팩토리(Abstract Factory) | 구체적인 클래스에 의존하지 않고, 인터페이스를 통해 서로 연관된 객체들을 생성하는 패턴 | - 서브 클래스에서 구체적인 객체를 생성 - 연관된 객체를 한 번에 교체 가능 |
빌더(Builder) | 복잡한 객체를 단계별로 생성하여, 동일한 객체 생성 방식에서도 서로 다른 객체를 만들 수 있도록 하는 패턴 | - 객체 조합을 하듯이 생성 - 생성 과정과 표현 방법을 분리 |
팩토리 메서드(Factory Method) | 객체 생성을 서브 클래스에서 담당하도록 하여 객체 생성의 결합도를 낮추는 패턴 | - 객체 생성을 캡슐화 - 상위 클래스에서 객체의 생성 방식 정의, 실제 생성은 서브 클래스가 담당 |
프로토타입(Prototype) | 기존 객체를 복사하여 새로운 객체를 생성하는 패턴 | - 원본 객체를 복제하여 객체를 생성 - 객체를 반복적으로 생성할 때 유용 |
싱글톤(Singleton) | 특정 클래스의 인스턴스를 하나만 유지하도록 보장하는 패턴 | - 하나의 인스턴스만 유지하며 전역적으로 공유 - 불필요한 메모리 낭비 방지 |
부가 설명
- 추상 팩토리 패턴은 서브 클래스에서 실제 객체를 생성하며, 연관된 객체를 일관성 있게 생성하는 데 적합하다.
- 빌더 패턴은 객체 생성이 복잡한 경우(예: HTML 문서, 데이터 변환 등) 단계적으로 생성하여 코드의 가독성을 높이는 데 도움이 된다.
- 팩토리 메서드 패턴은 객체 생성 로직을 서브클래스에서 담당하므로, 클라이언트 코드가 직접 객체를 생성할 필요가 없어 유연성이 증가한다.
- 프로토타입 패턴은 객체를 복사하여 생성하므로, 동일한 속성을 가지는 객체를 빠르게 생성할 수 있다.
- 싱글톤 패턴은 데이터베이스 연결, 설정 객체, 로그 관리 등 전역적으로 하나의 인스턴스만 필요한 경우에 유용하다.
생성 패턴은 객체 생성 방식의 유연성을 확보하여 코드의 유지보수성을 높이고, 결합도를 낮추는 데 효과적이다.
구조 패턴(Structural Pattern)
구조 패턴은 클래스나 객체들을 조합하여 더 큰 구조로 만들 수 있도록 도와주는 패턴으로, 시스템이 복잡해질 때 구조적인 문제를 해결하는 데 사용됩니다. 총 7개의 패턴이 있으며, 각 패턴은 유지보수성과 확장성을 고려하여 설계됩니다.
특징:
- 복잡한 시스템의 구조를 쉽게 설계하고 개발할 수 있도록 도와준다.
- 클래스 및 객체의 관계를 정의하여 코드의 재사용성을 높인다.
- 객체 간의 결합도를 줄여 유연한 시스템을 구성할 수 있다.
- 기능을 확장할 때 기존 코드를 수정하지 않고 새로운 기능을 추가하는 것이 가능하다.
구조 패턴의 종류
종류 | 설명 | 특징 |
어댑터(Adapter) | 서로 호환되지 않는 클래스들의 인터페이스를 변환하여 사용할 수 있도록 하는 패턴 | - 기존 클래스를 재사용하고 싶지만, 인터페이스가 일치하지 않을 때 사용 - 새로운 인터페이스를 추가하지 않고 기존 인터페이스를 변환하여 적용 |
브리지(Bridge) | 구현 부분과 추상 부분을 분리하여 서로 독립적으로 확장할 수 있도록 하는 패턴 | - 기능과 구현을 분리하여 확장성이 뛰어남 - 런타임에 구현을 동적으로 변경 가능 |
컴포지트(Composite) | 여러 개의 객체를 트리 구조로 구성하여 단일 객체와 복합 객체를 동일하게 다룰 수 있도록 하는 패턴 | - 부분-전체 계층 구조를 표현할 때 유용 - 클라이언트는 단일 객체와 복합 객체를 동일하게 처리 |
데코레이터(Decorator) | 객체의 결합을 통해 동적으로 기능을 확장할 수 있도록 하는 패턴 | - 기존 객체에 새로운 기능을 추가할 때 유용 - 상속을 사용하지 않고 동적으로 기능 추가 가능 |
퍼사드(Facade) | 복잡한 서브 시스템을 단순화하여 클라이언트가 쉽게 접근할 수 있도록 하는 패턴 | - 복잡한 서브 시스템을 감추고 간단한 인터페이스 제공 - 클라이언트와 서브 시스템 간의 결합도를 낮춤 |
플라이웨이트(Flyweight) | 객체 생성을 최소화하여 메모리를 절약하는 패턴 | - 대량의 유사한 객체를 생성해야 할 때 유용 - 공유 가능한 객체를 사용하여 메모리 절약 |
프록시(Proxy) | 다른 객체에 대한 접근을 제어하는 패턴 | - 원격 객체, 가상 객체, 보호 객체 등 다양한 방식으로 사용 가능 - 클라이언트가 실제 객체 대신 프록시 객체를 사용하여 접근 |
- 어댑터 vs. 브리지: 어댑터는 기존 인터페이스를 변환하여 사용하는 것이고, 브리지는 처음부터 추상화하여 독립적인 구현이 가능하도록 설계하는 방식입니다.
- 데코레이터 vs. 퍼사드: 데코레이터는 기존 객체의 기능을 확장하는 반면, 퍼사드는 복잡한 시스템을 단순화하는 데 초점이 맞춰져 있습니다.
- 플라이웨이트 vs. 프록시: 플라이웨이트는 객체를 공유하여 메모리 절약을 하는 것이고, 프록시는 실제 객체 대신 대리 객체를 사용하여 접근을 제어합니다.
행위 패턴(Behavioral Pattern)
행위 패턴은 클래스나 객체들이 서로 상호작용하는 방법과 책임을 분배하는 방식을 정의하는 패턴이다.
하나의 객체가 모든 작업을 수행하는 것이 아니라, 여러 객체가 협력하여 작업을 수행할 수 있도록 하며, 객체 간 결합도를 최소화하여 유지보수성과 확장성을 높이는 것이 주요 목적이다.
특징
- 객체 간의 상호작용을 정의하여 유연한 시스템을 구성할 수 있도록 한다.
- 객체들 간의 결합도를 최소화하여 독립성을 높인다.
- 책임을 분산시켜 코드의 가독성과 유지보수성을 높인다.
- 실행 흐름을 제어하고, 알고리즘을 캡슐화하여 재사용성을 높인다.
행위 패턴의 종류
패턴설명특징 및 활용
패턴 | 설명 및 특징 | 활용 |
책임 연쇄(Chain of Responsibility) | 요청을 처리할 객체를 연쇄적으로 구성하여 요청을 넘겨가며 처리하는 패턴 | - 요청을 처리할 여러 객체를 연결해 핸들링 가능 - 핸들러를 추가/삭제하여 동적으로 처리 가능 |
커맨드(Command) | 요청을 객체로 캡슐화하여 요청을 큐에 저장하거나 실행 취소할 수 있도록 하는 패턴 | - 요청을 객체화하여 저장 및 실행 취소 기능을 구현 - 실행 기능을 분리하여 클라이언트와 요청 수신자의 결합도를 낮춤 |
인터프리터(Interpreter) | 특정 언어의 문법을 정의하고 해석하는 패턴 | - 문법을 객체화하여 실행 가능하게 만듦 - SQL 파서, 정규 표현식 분석기 등에 활용 |
반복자(Iterator) | 집합 객체의 내부 표현을 노출하지 않고 요소를 순차적으로 접근하는 패턴 | - 컬렉션 요소를 순차적으로 접근 가능 - 내부 구조를 숨기고 일관된 인터페이스 제공 |
중재자(Mediator) | 객체 간의 직접적인 상호작용을 피하고 중재자를 통해 통신하도록 하는 패턴 | - 객체 간의 복잡한 의존 관계를 줄여 유연성 향상 - 이벤트 핸들러, 채팅 시스템 등에 활용 |
메멘토(Memento) | 객체의 상태를 저장하고 복원할 수 있도록 하는 패턴 | - 실행 취소(Undo) 기능 구현 가능 - 상태 저장을 외부에서 직접 접근하지 않고 캡슐화하여 보존 |
옵저버(Observer) | 특정 객체의 상태 변화가 있을 때, 이를 감지하여 관련 객체들에게 자동으로 알리는 패턴 | - 한 객체가 변경될 때, 연결된 객체들도 자동으로 업데이트됨 - GUI 이벤트 처리, 게시판 알림 시스템 등에 활용 |
상태(State) | 객체의 상태를 캡슐화하여 상태에 따라 행동을 다르게 수행하도록 하는 패턴 | - 상태 전환을 객체화하여 명확한 구조 제공 - 게임 캐릭터 상태 변화, TCP 연결 상태 관리 등에 활용 |
전략(Strategy) | 알고리즘을 인터페이스로 캡슐화하여 동적으로 변경할 수 있도록 하는 패턴 | - 실행 중에 알고리즘을 변경 가능 - 정렬 알고리즘, 경로 탐색 등에 활용 |
템플릿 메서드(Template Method) | 상위 클래스에서 알고리즘의 구조를 정의하고, 하위 클래스에서 세부 동작을 구현하는 패턴 | - 알고리즘의 기본 구조는 유지하면서 일부 세부 기능을 재정의 가능 - 중복 코드 최소화 및 유지보수성 향상 |
방문자(Visitor) | 객체 구조를 변경하지 않고 새로운 동작을 추가할 수 있도록 하는 패턴 | - 기존 클래스의 변경 없이 기능 추가 가능 - 복잡한 구조의 데이터 처리에 적합 |
옵저버 vs. 중재자:
- 옵저버 패턴은 특정 객체의 변경을 감지하고 여러 객체에 알림을 보내는 방식이고,
- 중재자 패턴은 여러 객체 간의 상호작용을 중앙에서 관리하여 결합도를 낮추는 방식입니다.
전략 vs. 상태:
- 전략 패턴은 런타임에 알고리즘을 선택하는 방식이고,
- 상태 패턴은 객체의 상태에 따라 동작을 다르게 수행하는 방식입니다.
책임 연쇄 vs. 중재자:
- 책임 연쇄는 요청을 여러 개의 핸들러가 순차적으로 처리하는 방식이고,
- 중재자는 객체들 간의 직접적인 연결을 제거하여 하나의 중재자가 상호작용을 조정하는 방식입니다.
출저 및 참고
정보처리 산업기사 기본서(시나공)
728x90
'자격증 > 정보처리' 카테고리의 다른 글
애플리케이션 테스트 (0) | 2025.02.01 |
---|---|
개발 지원 도구 (0) | 2025.01.31 |
객체지향 분석 및 설계 (0) | 2025.01.29 |
객체지향(Object-Oriented) (0) | 2025.01.29 |
아키텍처 패턴 (0) | 2025.01.29 |