디자인 패턴
heejeong Kwno님 블로그 참고 Wiki Docs Jeong-pro님 블로그 참고 소년코딩님 블로그 참고
디자인 패턴
소프트웨어 개발 시 어떤 특정한 상황에 자주 발생하는 문제들을 해결하기 패턴
- 추상화된 것에 의존하도록 만들어라. (구상 클래스에 의존하지 않도록 만든다.)
- 구현보다는 인터페이스를 이용한다.
- 상속 보다는 구성 (Composition). Is-A 보다는 Has-A.
- 다양하게 변하는 부분을 때어서 캡슐화한다.
디자인 패턴의 구조
- Context
- 문제가 발생하는 상황 기술
- 유용하지 못한 상황도 기술
- Problem
- 해결할 필요가 있는 여러 디자인 이슈 기술
- 제약 사항과 영향력도 함께 고려
- Solution
- 문제를 해결하도록 설계를 구성하는 요소들과, 요소들 사이 관계
- 구체적인 방법이나 언어에 의존적이지 않은 탬플릿 이여야함
GoF 디자인 패턴
- GoF(Gang of Fout)라 불리는 사람들이 디자인 패턴 구체화 및 체계화
- 에리히 감마(Erich Gamma), 리차드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리시디스(John Vissides)
GoF 디자인 패턴의 분류
생성(Creational) 패턴
객체 생성에 관한 패턴
- Factory
- 객체 생성을 캡슐화 한다.
- Factory Method : 객체를 생성하기 위한 인터페이스를 정의하고, 어떤 클래스의 인터페이스를 만들지는 서브 클래스에서 결정한다.
- Abstract Factory (Kit) : 인터페이스를 이용 서로 연관되거나 의존하는 객첼를 구상 클래스 지정 없이도 생성할 수 있게한다.
- Builder
- 제품을 여러 단계로 나누어 만들 수 있도록 제품 생산 단계들을 캡슐화한다고 생각하면됨
- 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서 서로 다른 표현을 가능하도록 하는 패턴
- Prototype
- 생성할 객체의 종류의 원형이 되는 예시물을 이용해, 그 원혀을 복제해 새로운 객체를 생성하는 패턴
- 어떤 객체를 생성할 때 자원이나 시간을 많이 잡아먹는 경우 사용
- Singleton
- 전역 변수를 사용하지 않고 하나의 객체만 생성하도록 하여, 생성된 객체를 어디서든지 참조할 수 있도록 하는 패턴
구조(Structural) 패턴
클래스나 구조를 결합하여 더 큰 구조를 만드는 패턴
- Adapter
- 클래스의 인터페이스를 사용자가 원하는 다른 인터페이스로 변환하는 패턴
- Wrapper 패턴이라고도 함
- Bridge
- 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴
- Composite
- 여러 개의 객체들로 구성된 복합 객체와, 단일 객체를 클라이언트에서 구별 없이 다루게 해주는 패턴
- Decorator
- 다른 객체에 영향을 주지 않고 조건을 추가하고 싶을 때 기존에 존재하던 객체에 장식을 더하는 것과 같이 만들 수 있음
- Facade
- 서브시스템 내의 인터페이스에 대해 하나의 통합된 인터페이스를 만들어 서브 시스템 사용을 편리하게 하는 패턴
- Flyweight (경량)
- 크기가 작은 객체가 여러 개 있을 때, 공유를 통해 이들을 효율적으로 지원하는 패턴
- 크기가 작은 클래스에서 공유하는(값이 같은) 멤버 변수가 존재할 경우, 해당 멤버 변수를 표현하는 구조체나 클래스를 새로 만들어 이를 포인터로 공유하도록 할 수 있음
- Proxy
- 어떤 다른 객체가 접근하는 것을 통제하기 위해 해당 객체의 대리자(Surrogate) 혹은 자리채움자(Placeholder)를 제공하는 패턴
- 다른 객체 접근 통제를 위해 대리자 제공
- C++의 포인터와 스마트 포인터가 한 예
- 프록시 클래스는 주체 클래스를 감싸면서 주체 클래스에게 실질적인 요청을 위임한다.
- 프록시 클래스는 주체 클래스의 경량화 버전으로 볼 수도 있다.
- Virtual proxy : 리소스 집약적인 객체 필요 전까지 라이트한 버전의 프록시 클래스로 전처리 등 가능
- Protection proxy : 주체 클래스에 접근하는 것을 제한 가능
- Remote proxy : 원격 혹은 가상에 있는 시스템을 로컬에 있는 것처럼 표현 가능
행위(Behavioral) 패턴
객체나 클래스 사이의 알고리즘 혹은 책임 분배에 관련된 패턴
- Chain of Responsibility
- 요청을 처리하는 객체들을 여러 개 만들어 요청하는 객체와 요청 받는 객체의 결합을 피하기 위한 패턴
- 요청 받을 수 있는 객체를 여러 개 묶고, 요청 처리가 가능한 객체를 만날 때까지 체인을 따라 요청 전달
- Command (명령)
- 요청을 객체 형태로 캡슐화하여 사용
- 함수 호출을 객체로 감싸 콜백을 객체 지향적으로 표현한 것
- 요청 저장, 로깅, 연산 취소를 가능하게함
- Interpreter
- 주어진 언어에 대해 해당 언어의 문법을 위한 표현 수단을 정의하고, 표현 수단을 사용하여 해당 언어로 작성된 문장을 해석하는 해석기를 정의하는 패턴
- Iterator
- 내부 표현을 노출하지 않고, 어떤 객체 안의 원소들을 순차적으로 접근할 수 있게 해주는 패턴
- C++이나 Java의 Iterator
- Mediator (중재자)
- 한 집합 안의 객체들의 상호작용을 캡슐화해 객체를 정의하는 패턴
- 객체들이 직접 서로 참조하지 않게 해 Loose Coupling (소결합)
- 서비스를 사용하는 객체가 서비스가 누구인지 구체적인 정보 없이도 되게 해줌
- Memento
- 객체를 이전 상태로 복구시킬 수 있어야 할 경우 사용하는 패턴
- Observer (관찰자)
- 한 객체의 상태가 변한다면 다른 객체의 상태도 연동되도록 일대다 객체 의존 관계를 구성하는 패턴
- 객체 사이에 일대 다의 의존 관계를 정의하여, 어떤 객체의 상태가 변할 때 해당 객체에 의존성을 가진 다른 객체들이 그 변화를 통지 받고 자동으로 업데이트 될 수 있게함
- 옵저버 클래스는 관찰할 대상 객체들의 리스트를 가지고 있다가, 이벤트가 발생하면 해당 리스트로 알림을 보내줌
- State
- 객체의 상태에 따라 객체의 행위 내용을 변경하는 패턴
- 상태를 나타내는 클래스에 메소드를 위임했다고 보면됨
- Strategy
- 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
- 객체마다 다를 수 있는 행위(메소드) 부분을 캡슐화해 교환하여 사용할 수 있도록하는 패턴
- 각 클래스에 인터페이스를 구현하는 것이 아닌, 인터페이스의 구현체들을 각 객체에 할당해줘 행위를 자유롭게 바꿔줄 수 있음. Is-A 보다 Has-A가 좋은 부분이다.
- Template Method
- 탬플릿을 만들어주고, 해당 메소드 안을 채워 넣기만하면 되는 디자인 패턴
- 하위 클래스에서 실제 메소드 구현, 일반적인 abstract 함수를 Override하는 것이라고 봐도 무방
- Visitor
- 객체 구조를 이루는 원소에 대해 수행할 연산을 표현하는 패턴
- 연산을 적용할 원소의 클래스르 변경하지 않고도 새로운 연산을 정의할 수 있게 함