디자인 패턴 27

[C#] Provider(공급자) - Observer(관찰자) 패턴

Provider - 이벤트를 발생시키면서(제공하면서) Observer를 관리하는 개체 자신이 관리하고 있는 Observer에 대하여 Subscribe하는 방법을 갖고 있고 이벤트 발생 함수를 invoke 한다. Observer - Provider가 발생시키는 이벤트를 구독한다. Observer는 Provider에 Subscibe 함수로 구독을 실행하고 그 반환 Unsubscribe 클래스 개체를 소유한다. Observer는 원할 때 Unbsubscribe 개체 인스턴스를 이용하여 구독을 취소한다. C# Provider는 IObserable 인터페이스를 구현한다. public interface IObservable { IDisposable Subscribe(IObserver observer); } IDis..

[디자인 패턴] Modern C++ Singleton

모던 C++ 스타일 싱글턴 패턴을 템플릿으로 구현한다. 구현점 1. 멀티 스레드에 안전한, 전역적으로 딱 한번만 초기화하여 인스턴스가 유일함을 보장한다. 2. 템플리 클래스로 정의하고 GetInst()에서 구체 클래스의 생성자를 호출하므로 구체 클래스에서 싱글톤클래스를 friend로 선언해야한다. 3. unique_ptr의 삭제자 구조체를 선언하고 스마트포인터 인스턴스 생성시 이 호출가능한 구조체의 인스턴스를 넘겨준다. - 템플릿 클래스에서 virtual 소멸자로 선언했기 때문에 구체 클래스에서 삭제할 멤버가 있다면 편하게 소멸자를 정의할 수 있다. - 소멸자를 private로 선언해도 unique_ptr에서 private 소멸자를 찾을 수 없다는 에러를 없앨 수 있다. #pragma once #incl..

[디자인 패턴] 행동 패턴 (11) 템플릿 메서드 Template Method

템플릿 메서드 (Template Method) 패턴 1. 의도 객체 연산에 알고리즘의 뼈대만 정의하고 알고리즘을 구성하는 연산의 구현은 서브 클래스로 미룬다. 2. 활용 Application 클래스와 Document 클래스를 제공하는 응용프로그램의 프레임워크의 예를 들어보자. Application의 클래스는 Document에 관한 연산들을 선언하고 있고 Document는 실제 문서를 열고 저장하고 닫는 연산을 선언한다. Applcation 클래스는 Document 인스턴스를 소유하며 이에 대한 OpenDocument 연산의 예시를 보면, void Application::OpenDocument (const char* name) { if(!CanOpenDocument(name) { // 이 문서를 처리할 수..

[디자인 패턴] 행동 패턴 (10) 방문자 Visitor

방문자 (Visitor) 패턴 1. 의도 객체 내부 원소에 대해 수행할 연산을 표현하는 방법. 연산을 적용할 원소의 클래스를 변경하지 않고 새로운 연산을 정의한다. 2. 활용 - 추상 구문트리 프로그램 코드를 구성하는 구문의 의미를 분석하는 컴파일러가 있다 하자. 컴파일러는 트리 구조의 코드를 추적하며 각 구문이 의미하는 변수 타입, 최적화, 흐름 분석, 문법 검사 등을 수행할 것이다. 이러한 연산을 각 구문을 구성하는 노드에 정의하면 다음과 같이 클래스 구조가 정의된다. 위와 같이 새로운 노드 클래스를 정의할 때마다 그에 맞는 컴파일러 연산을 정의해야한다. 문제는 이러한 연산이 클래스 전반적으로 퍼져있기 때문에 컴파일러 연산에 대한 유지보수와 새로운 기능 정의 등이 어렵다는 점이다. 따라서 각 노드에 ..

[디자인 패턴] 행동 패턴 (9) 메멘토 Memento

메멘토 (Memento) 패턴 1. 의도 어떤 객체의 내부 상태를 기록하는 상태 객체를 관리하고 필요할 때 지난 상태로 돌아갈 수 있도록 한다. 2. 활용 게임 플레이어의 체크포인트를 기록하거나 그래픽/텍스트 편집기에서 실행했던 명령을 되돌리는 방법, 오류에서 복구하는 방법 등 활용성이 높은 기능으로 과거의 상태나 명령들을 저장해두었다 필요할 때 거꾸로 되돌리기 위해 필요한 정보를 제공한다. 그러한 기능이 필요한 객체의 모든 정보를 노출시키지 않고 상태에 쓰이는 정보만 주기적으로 저장하며 필요할 때 요청하도록한다. 그래픽 편집기의 그리기 명령어와 되돌리기 수행 절차 1. 편집기는 사용자가 마우스로 다양한 객체를 그릴 때마다 메멘토에 요청하여 현재 상태를 저장하도록 한다. 2. 메멘토는 필요한 상태 정보를..

[디자인 패턴] 행동 패턴 (8) 반복자 Iterator

반복자 (Mediator) 패턴 1. 의도 자료구조에서 흔히 쓰이는 패턴으로 속한 원소에 대한 순차적 접근 방법을 제공하고 방법에 대한 표현을 외부에 노출하지 않는다. 2. 활용 리스트와 같이 원소에 대한 접근과 다음 원소로 이동하는 방법이 존재하는 자료구조에서 모든 원소를 순차적으로 접근하는 방법을 구현한다. 순차적 접근을 통해 반복자 함수 내부에서 삽입, 삭제 등의 연산을 포함시킬 수 있다. 이를 위해 반복자는 현재 몇 번째 원소를 가리키고 있는지, 자료구조의 끝에 도달했는 지를 판별한다. - ListIterator와 List 반복자는 어떤 자료구조냐에 따라 순회 방법이 다르다. List와 같이 선형적 탐색 혹은 반대 방향으로 가능할 수도 있고 Tree같은 경우 전위, 중위, 후위 탐색 혹은 레벨 탐..

[디자인 패턴] 행동 패턴 (7) 중재자 Mediator

중재자 (Mediator) 패턴 1. 의도 같은 집합에 속해있는 객체들의 상호작용을 중재해주는 객체를 정의하고 상호작용을 하는 객체 간 결합도를 낮추도록 한다. 2. 활용 객체간의 상호작용에는 먼저 사건이 발생하고 다른 객체가 영향을 받는 등의 종속성이 존재하게 되는데, 이 복잡한 관계를 중재하고 객체 들은 서로 참조자를 관리하지 않고 중재자 객체만 알도록 하여 결합도를 낮추도록 한다. 결합도를 낮추게 되면 관리되는 객체들의 재사용성을 증가시킬 수 있다. - FontDialogDirector 클래스 FontDialogDirector 객체는 대화 상자를 구성하는 위젯 간의 상호작용을 중재한다. 대화 상자를 구성하는 요소중 ListBox는 마우스로 클릭할 수 있는 모든 리스트 정보를 관리한다. 사용자가 마우..

[디자인 패턴] 행동 패턴 (6) 전략 Strategy

전략(Strategy) 패턴 1. 의도 객체가 사용하는 알고리즘을 추상화하고 선택적으로 사용할 수 있게 해준다. 2. 활용 공통성이 없는 여러 객체가 비슷한 알고리즘을 사용할 때, 함수를 객체로 만들어 사용하면 유용하다. 이에 대한 함수를 추상화하여 클래스로 정의하고 인스턴스를 만들 때 알고리즘을 선택할 수 있게 한다. - UI 화면에 띄울 문자를 파싱하여 자동으로 라인을 분리하는 객체 Composition 객체는 화면에 띄울 문자를 모두 가지고 있으며 라인 분리 알고리즘을 사용할 주체이다. Composition 객체는 직접 알고리즘을 구현하지 않으며, Compositor라는 클래스에 알고리즘을 구현하여 사용한다. Compositor 객체는 UI 화면에 띄울 문자와 라인 분리를 위한 문자 넓이, 라인 1..

[디자인 패턴] 행동 패턴 (5) 감시자 Observer

감시자 (Observer) 패턴 1. 의도 객체 사이에 一 대 多의 의존 관계를 정의하여 어떤 객체의 상태가 변할 때 그 객체를 관찰하는 감시자에게 변화를 통보하고 변화된 상태를 알 수 있게 한다. 2. 활용 감시자 패턴은 서로 의존적인 두 클래스가 일관성을 갖도록 하는 것이다. 일관성을 가지면서 두 클래스의 결합도를 높이지 않아 각 클래스의 재사용성을 높이는데 목적이 있다. - Subject-Observer 예시 의존적인 관계를 가지는 두 클래스르 Subject-Observer라고 할 수 있고 이를 설명하기 위해 데이터와 그래프 자료를 예로 들 수 있다. 데이터 자료형을 스프레드 시트나 그래프로 나타내는 GUI 객체들이 있는데 이들은 모두 실제 데이터에 의존적인 모습을 보인다. 데이터가 변경되면 그에 ..

[디자인 패턴] 행동 패턴 (4) 상태 State

상태 (State) 패턴 1. 의도 객체 상태에 따라 행동이 다르고 행동은 다른 상태 전이를 발생시킬때 사용하는 패턴. 2. 활용 - TCP 연결 네트워크 연결을 추상화한 TCPConnection 클래스를 생각해보면 TCPConnection 클래스는 여러가지 상태를 가질 수 있다. 연결 성공(Established), 대기(Listening), 연결 종료(Closed) 상태를 가지는데 TCP-Connection 객체는 자신의 상태에 따라 사용자 요청에 대한 처리 결과가 다르다. ex) Open 요청은 종료 상태에서만 의미가 있을 수 있고 Acknowledge() 요청은 전송된 패킷을 성공적으로 수신했다는 패킷을 보내는 것이므로 대기나 연결 성공 상태에서 의미가 있는 연산이다. - TCPState 추상 클래..