[7] [数据结构] ( 3 ) 职责链 ChainofResposibility
总结
-
GOF定义?
使多个对象都有机会处理请求,
从而避免请求的发送者和接收者(handler)之间的耦合关系。
将这些对象连成一条链,(链表)
并沿着这条链传递请求,
直到有一个对象处理它为止.
.
运行时再确定哪一个handler可以处理这个request.
.
过程像踢皮球一样.
-
解耦谁?
将请求的发送者和接受者解耦.
-
好处?
添加新的handler或者修改现有的handler,
不用改动其他handler的代码,
每一个handler处理特定的任务,
代码更加模块化.
-
缺点?
性能开销大
调试复杂
-
场景?
web框架中间件
GUI事件处理
异常处理
java例子1
重构前
package v22_chain_of_responsibility.java;
class Logger {
public static final int ERROR = 1;
public static final int DEBUG = 2;
public static final int INFO = 3;
private int level;
public Logger(int level) {
this.level = level;
}
// 处理者
public void logMessage(int logLevel, String message) {
// 每次添加新的日志类型, 都需要改动这里的if else.
if (logLevel == ERROR && logLevel <= level) {
System.out.println("Error: " + message);
} else if (logLevel == DEBUG && logLevel <= level) {
System.out.println("Debug: " + message);
} else if (logLevel == INFO && logLevel <= level) {
System.out.println("Info: " + message);
}
}
}
public class LoggerDemo1 {
public static void main(String[] args) {
Logger logger = new Logger(Logger.INFO);
// 发送者
logger.logMessage(Logger.ERROR, "This is an error message");
logger.logMessage(Logger.DEBUG, "This is a debug message");
logger.logMessage(Logger.INFO, "This is an info message");
}
}
重构后
package v22_chain_of_responsibility.java;
abstract class Logger {
protected int level;
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int logLevel, String message) {
if (logLevel <= level) {
write(message);
} else if (nextLogger != null) {
nextLogger.logMessage(logLevel, message);
}
}
abstract protected void write(String message);
}
class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error: " + message);
}
}
class DebugLogger extends Logger {
public DebugLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Debug: " + message);
}
}
class InfoLogger extends Logger {
public InfoLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Info: " + message);
}
}
public class LoggerDemo2 {
public static void main(String[] args) {
ErrorLogger errorLogger = new ErrorLogger(1);
DebugLogger debugLogger = new DebugLogger(2);
InfoLogger infoLogger = new InfoLogger(3);
errorLogger.setNextLogger(debugLogger);
debugLogger.setNextLogger(infoLogger);
errorLogger.logMessage(1, "This is an error message");
errorLogger.logMessage(2, "This is a debug message");
errorLogger.logMessage(3, "This is an info message");
}
}
java例子2
package v22_chain_of_responsibility.java;
// 抽象handler
interface DispenseChain {
void setNextChain(DispenseChain nextChain); // 设置下一个接点
void dispense(Currency currency); // 派发
}
// request / 货币
class Currency {
private int amount; // 额度
public Currency(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
// 具体handler 50
class Dollar50Dispenser implements DispenseChain {
private DispenseChain chain;
@Override
public void setNextChain(DispenseChain nextChain) {
this.chain = nextChain;
}
@Override
public void dispense(Currency currency) {
if (currency.getAmount() >= 50) {
// 面额大于50
int numberOfNotes = currency.getAmount() / 50; // 计算有几个50面额
int remainder = currency.getAmount() % 50; // 计算零头
// 把50面额的处理掉
System.out.println("Dispensing " + numberOfNotes + " 50$ note");
// 如果有零头,进行责任派发
if (remainder != 0) {
this.chain.dispense(new Currency(remainder));
}
} else {
// 面额小于50, 直接进行责任派发
this.chain.dispense(currency);
}
}
}
// 具体handler 20
class Dollar20Dispenser implements DispenseChain {
private DispenseChain chain;
@Override
public void setNextChain(DispenseChain nextChain) {
this.chain = nextChain;
}
@Override
public void dispense(Currency currency) {
if (currency.getAmount() >= 20) {
int numberOfNotes = currency.getAmount() / 20;
int remainder = currency.getAmount() % 20;
System.out.println("Dispensing " + numberOfNotes + " 20$ note");
if (remainder != 0) {
this.chain.dispense(new Currency(remainder));
}
} else {
this.chain.dispense(currency);
}
}
}
// 具体handler 10
class Dollar10Dispenser implements DispenseChain {
private DispenseChain chain;
@Override
public void setNextChain(DispenseChain nextChain) {
this.chain = nextChain;
}
@Override
public void dispense(Currency currency) {
if (currency.getAmount() >= 10) {
int numberOfNotes = currency.getAmount() / 10;
int remainder = currency.getAmount() % 10;
System.out.println("Dispensing " + numberOfNotes + " 10$ note");
if (remainder != 0) {
this.chain.dispense(new Currency(remainder));
}
} else {
this.chain.dispense(currency);
}
}
}
// 客户端
public class ATMDispenser {
private DispenseChain c1;
public ATMDispenser() {
// initialize the chain
this.c1 = new Dollar50Dispenser();
DispenseChain c2 = new Dollar20Dispenser();
DispenseChain c3 = new Dollar10Dispenser();
// 设定责任链
c1.setNextChain(c2);
c2.setNextChain(c3);
}
public void dispenseMoney(Currency currency) {
if (currency.getAmount() % 10 != 0) {
System.out.println("金额应为 10 的倍数.");
return;
}
// process the request
c1.dispense(currency);
}
public static void main(String[] args) {
ATMDispenser atmDispenser = new ATMDispenser();
Currency currency = new Currency(370);
atmDispenser.dispenseMoney(currency);
}
}


c++例子
#include <iostream>
#include <string>
using namespace std;
enum class RequestType
{
REQ_HANDLER1,
REQ_HANDLER2,
REQ_HANDLER3
};
class Reqest
{
string description;
RequestType reqType;
public:
Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
RequestType getReqType() const {
return reqType;
}
const string& getDescription() const {
return description;
}
};
class ChainHandler{
ChainHandler *nextChain;
void sendReqestToNextHandler(const Reqest & req)
{
if (nextChain != nullptr)
nextChain->handle(req);
}
protected:
virtual bool canHandleRequest(const Reqest & req) = 0;
virtual void processRequest(const Reqest & req) = 0;
public:
ChainHandler() {
nextChain = nullptr;
}
void setNextChain(ChainHandler *next) {
nextChain = next;
}
void handle(const Reqest & req){
if (canHandleRequest(req))
processRequest(req);
else
sendReqestToNextHandler(req);
}
};
class Handler1 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER1;
}
void processRequest(const Reqest & req) override
{
cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
}
};
class Handler2 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER2;
}
void processRequest(const Reqest & req) override
{
cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
}
};
class Handler3 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER3;
}
void processRequest(const Reqest & req) override
{
cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
}
};
int main(){
Handler1 h1;
Handler2 h2;
Handler3 h3;
h1.setNextChain(&h2);
h2.setNextChain(&h3);
Reqest req("process task ... ", RequestType::REQ_HANDLER3);
h1.handle(req);
return 0;
}


浙公网安备 33010602011771号