Published on

设计模式(13)——职责链 Chain Of Responsibility

Authors
  • avatar
    Name
    Leon
    Twitter

十三、Chain Of Responsibility (职责链,对象行为模式)

1. 意图:

  使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2. 适用:

  1. 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  2. 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  3. 可处理一个请求的对象集合应被动态指定。

3. 类图:

4. 例:

  c++ 的异常处理就是一种职责链的模式,当程序出现异常的时候,就会一层一层往外抛,直到异常被处理。我们可以动态地添加异常处理代码,去处理异常。

5. C++实现:

  1. 先编写一个父类或接口 Handlehas-a 后继节点Handle对象 private Handle* _succ;
  2. 编写初始化后继节点代码: 2.1 通过构造函数 Handle(Handle* succ){this->_succ = succ;} 2.2 编写Set函数 void SetSuccessor(Handle* succ){_succ = succ;} 2.3 编写处理请求(职责)方法 HandleRequest(); 2.4 编写一些子类或实现类如 ConcreteHandleA、ConcreteHandleB等,调用相关初始化后继节点方法,实现职责链(链表)

Handle.h

//Handle.h
#pragma once
class Handle {
public:
	virtual ~Handle();
	virtual void HandleRequest() = 0;
	void SetSuccessor(Handle* succ);
	Handle* GetSuccessor();
protected:
	Handle();
	Handle(Handle* succ);
private:
	Handle* _succ;
};

class ConcreteHandleA : public Handle {
public:
	ConcreteHandleA();
	~ConcreteHandleA();
	ConcreteHandleA(Handle* succ);
	void HandleRequest();
protected:
private:
};

class ConcreteHandleB : public Handle {
public:
	ConcreteHandleB();
	~ConcreteHandleB();
	ConcreteHandleB(Handle* succ);
	void HandleRequest();
protected:
private:
};

Handle.cpp

//Handle.cpp
#include "Handle.h"
#include <iostream>
using namespace::std;

Handle::Handle() {
	_succ = 0;
}
Handle::Handle(Handle* succ) {
	_succ = succ;
}
Handle::~Handle() {
	delete _succ;
}
void Handle::SetSuccessor(Handle* succ) {
	_succ = succ;
}
void Handle::HandleRequest() {}
Handle* Handle::GetSuccessor(){
	return _succ;
}

ConcreteHandleA::ConcreteHandleA() {}
ConcreteHandleA::ConcreteHandleA(Handle* succ) : Handle(succ){}
ConcreteHandleA::~ConcreteHandleA() {}

void ConcreteHandleA::HandleRequest() {
	if (this->GetSuccessor() != 0) {
		cout << "ConcreteHandleA 我把处理权给后继节点......" << endl;
		this->GetSuccessor()->HandleRequest();
	}
	else {
		cout << "ConcreteHandleA 没有后继节点了,我必须自己处理......" << endl;
	}
}

ConcreteHandleB::ConcreteHandleB() {}
ConcreteHandleB::ConcreteHandleB(Handle* succ) : Handle(succ) {}
ConcreteHandleB::~ConcreteHandleB() {}
void ConcreteHandleB::HandleRequest() {
	if (this->GetSuccessor() != 0) {
		cout << "ConcreteHandleB 我把处理权给后继节点......" << endl;
		this->GetSuccessor()->HandleRequest();
	}
	else {
		cout << "ConcreteHandleB 没有后继了,我必须自己处理......" << endl;
	}
}

main.cpp

// main.cpp
#include "Handle.h"
#include <iostream>

using namespace::std;

int main(int argc, char* argv[]) {
	Handle* h1 = new ConcreteHandleA();
	Handle* h2 = new ConcreteHandleB();
	h1->SetSuccessor(h2);
	h1->HandleRequest();
	return 0;
}