티스토리 뷰
요청을 처리하는 수신측과 송신측의 결합도를 줄여주는 패턴
요정을 보내는 송신특은 자신이 알고있는 객체에게 요청을 보낸다. 수신측은 자신이 그 요청을 처리할 수 있으면 서비스를 제공하고, 아니라면 자신이 알고있는 다음 객체에게 요청을 전달한다.
이런 연쇄를 구현하기 위해 수신 객체들은 하나의 부모 클래스를 두어 인터페이스를 통일시켜야 한다.
* 구조를 그리고 싶다.
결과
객체간의 행동 결합도를 줄인다.
송신측과 수신측이 서로를 몰라도 메세지 전달이 가능하다.
수신측은 자신과 연결된 하나의 객체만 알고 있으면 된다.
객체에 책임을 할당하는데 유연성을 높인다.
런타임 중에 연결고리를 변경하거나 추가하여 확장시킬 수 있다.
메세지의 처리가 보장되지 않는다.
연결고리가 잘 정의되어 있지 않다면 메세지가 전달만 되다가 버려질 수 있다.
구현
- 요청의 매개변수 전송 문제를 해결하기 위해 매개변수를 묶어 하나의 객체로 만드는 기법을 사용할 수 있다. ( Request )
Request에 GetKind 연산을 구현하여 요청을 식별하도록 만들 수 있다.
- 수신객체의 부모 클래스에서 연결고리의 다음 객체에 대한 참조자를 정의한다. ( successor )
- int변수 등으로 제공할 서비스가 있는지 식별하도록 할 수 있다.
* -1이면 제공할 서비스가 없다.
아니라면 서비스를 제공한다.
- 생성자는 연결고리의 다음 객체와 서비스 식별자를 전달받는다.
- 연결고리의 끝 객체는 HasHelp를 검사하지 않고 바로 서비스를 제공한다. ( 기저 서비스 )
* HasHelp는 식별자가 -1인지 검사한다. 제공할 서비스가 있다면 true를 반환한다.
도움말 시스템을 만들면서 연쇄 패턴이 어떻게 구현되는지 생각해보자.
class HelpHandler{
public:
HelpHandler(HelpHandler*, int=-1);
virtual bool HasHelp();
virtual void HandleHelp(); // 재정의 필요
private:
HelpHandler* successor; // 다음 연쇄 객체
int topic; // 내 도움말 식별자
};
void HelpHandler::HandleHelp(){
if(successor)
successor->HandleHelp(); // 요청을 다음 객체에 전달
}
// HelpHandler를 상속받은 Widget class
class Widget : public HelpHandler{
protected:
Widget(Widget* w, int t=-1);
private:
Widget* parent;
};
Widget::Widget(Widget* w, int t)
:HelpHandler(w, t){
parent = w;
}
Widget은 모은 위젯의 추상클래스이며 HelpHandler의 서브클래스다.
책임을 전가할 객체는 객체 구조에서 더 깊은( 높은 ) 객체일 확률이 높으므로 parent가 된다.
* Button이 제공할 도움말이 없다면 Dialog가 제공할 것이고, 그도 없다면 Application이 제공할 것이다.
// Widget을 상속받은 Button class
class Button : public Widget{
public:
void HandleHelp();
};
void Button::HandleHelp(){
if(HasHelp())
// 서비스 제공
else
HelpHandler::HandleHelp(); // 요청 전달
}
Button은 요청을 받고 서비스를 제공할 수 있으면 제공하며, 제공할 서비스가 없을 경우 최상위 클래스의 HandleHelp를 호출하여 메세지를 전달한다.
* 가상함수를 사용하는거랑 무슨 차이가 있는걸까
가상함수는 클래스 구조상 부모 클래스에게만 책임전가 할 수 있지만 연쇄 패턴은 같은 클래스 레벨이어도 인스턴스의 구조에 따라 책임을 전가할 수 있다.
* Button에 수많은 기능이 있는데 생성자에서 도움말 식별자를 꼭 받아야 하나. 낭비가 아닐까
'Programming > Design' 카테고리의 다른 글
Design Pattern - 옵저버 패턴 Observer (0) | 2021.03.08 |
---|
- Total
- Today
- Yesterday
- ios
- Git
- 자료구조
- 수학
- 드라마
- C
- 운영체제
- ue4
- game
- machine learing
- database
- 데이터베이스
- 국내여행
- Java
- C++
- SwiftUI
- Cocos2d-x
- 알고리즘
- SHADER
- DesignPattern
- SOCKET
- winsock
- scala
- OS
- C/C++
- Spring
- mongoDB
- JSP
- swift
- rxswift
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |