C++ 设计模式之责任链模式
简介
1、责任链模式 (Chain of Responsibility):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2、责任链模式 (Chain of Responsibility)应用场景包括但不限于:
2.1、当有多个对象可以处理同一个请求时,具体哪个对象处理该请求由运行时刻自动确定。
2.2、当你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求时。
2.3、当你想在不必指定具体接收者的前提下,向一个或多个对象发出请求时。
3、责任链模式 (Chain of Responsibility)的构成
3.1、抽象处理者(Handler):定义一个处理请求的接口,包含一个处理请求的抽象方法和一个指向下一个处理者的引用。
c
class Logger
{
public:
Logger(LogLevel level);
void setNext(std::shared_ptr<Logger> nextLogger);
void logMessage(LogLevel level, const std::string& message);
virtual void write(const std::string& message) = 0;
protected:
LogLevel logLevel;
std::shared_ptr<Logger> next;
};
3.2、具体处理者(Concrete Handler):实现抽象处理者的方法,判断能否处理请求,如果能够处理请求则进行处理,否则将请求传递给下一个处理者。
c
class InfoLogger : public Logger
{
public:
InfoLogger(LogLevel level);
void write(const std::string& message);
};
4、责任链模式 (Chain of Responsibility)的优点
4.1、减少耦合度:它将请求的发送者和接收者解耦。
4.2、增强了对象的责任:通过改变链内的成员或调整它们的顺序,允许动态地新增或删除责任。
4.3、增加了灵活性:可以在运行时改变链中处理者的顺序和数量。
4.4、简化对象:对象只需要知道如何将请求发送到链上,而不需要知道链的结构细节。
4.5、分布请求处理:可以让多个对象都有机会处理请求,从而将单个请求的处理分散到多个类中。
5、责任链模式 (Chain of Responsibility)的缺点
5.1、请求可能未被处理:在某些情况下请求可能会到达链的末尾都没有被处理。
5.2、性能问题:由于请求的处理经过多个对象,可能会影响性能。
5.3、复杂性增加:系统设计更加复杂,需要维护链中的顺序。
5.4、调试难度大:由于请求在链中传递的过程中可能会变得难以追踪,使得问题难以定位。
简单示例
1、定义
c
// 日志级别常量
enum LogLevel {
NONE = 0,
INFO = 1,
DEBUG = 2,
WARNING = 3,
ERROR = 4
};
// 抽象基类
class Logger
{
public:
Logger(LogLevel level);
void setNext(std::shared_ptr<Logger> nextLogger);
void logMessage(LogLevel level, const std::string& message);
virtual void write(const std::string& message) = 0;
protected:
LogLevel logLevel;
std::shared_ptr<Logger> next;
};
// INFO级别的日志处理者
class InfoLogger : public Logger
{
public:
InfoLogger(LogLevel level);
void write(const std::string& message);
};
// DEBUG级别的日志处理者
class DebugLogger : public Logger
{
public:
DebugLogger(LogLevel level);
void write(const std::string& message);
};
// WARNING级别的日志处理者
class WarningLogger : public Logger
{
public:
WarningLogger(LogLevel level);
void write(const std::string& message);
};
// ERROR级别的日志处理者
class ErrorLogger : public Logger
{
public:
ErrorLogger(LogLevel level);
void write(const std::string& message);
};
2、实现
c
Logger::Logger(LogLevel level) : logLevel(level)
{
}
void Logger::setNext(std::shared_ptr<Logger> nextLogger)
{
next = nextLogger;
}
void Logger::logMessage(LogLevel level, const std::string& message)
{
if (logLevel <= level)
{
write(message);
}
if (next)
{
next->logMessage(level, message);
}
}
InfoLogger::InfoLogger(LogLevel level) : Logger(level)
{
}
void InfoLogger::write(const std::string& message)
{
if (logLevel == LogLevel::INFO)
{
std::cout << "Info: " << message << std::endl;
}
}
DebugLogger::DebugLogger(LogLevel level) : Logger(level)
{
}
void DebugLogger::write(const std::string& message)
{
if (logLevel == LogLevel::DEBUG)
{
std::cout << "Debug: " << message << std::endl;
}
}
WarningLogger::WarningLogger(LogLevel level) : Logger(level)
{
}
void WarningLogger::write(const std::string& message)
{
if (logLevel == LogLevel::WARNING)
{
std::cout << "Warning: " << message << std::endl;
}
}
ErrorLogger::ErrorLogger(LogLevel level) : Logger(level)
{
}
void ErrorLogger::write(const std::string& message)
{
if (logLevel == LogLevel::ERROR)
{
std::cout << "Error: " << message << std::endl;
}
}
3、调用
c
auto infoLogger = std::make_shared<InfoLogger>(LogLevel::INFO);
auto debugLogger = std::make_shared<DebugLogger>(LogLevel::DEBUG);
auto warningLogger = std::make_shared<WarningLogger>(LogLevel::WARNING);
auto errorLogger = std::make_shared<ErrorLogger>(LogLevel::ERROR);
infoLogger->setNext(debugLogger);
debugLogger->setNext(warningLogger);
warningLogger->setNext(errorLogger);
// 构建完整的责任链,从INFO到ERROR
infoLogger->logMessage(LogLevel::INFO, "This is an informational message.");
std::cout << std::endl;
infoLogger->logMessage(LogLevel::DEBUG, "This is a debug message.");
std::cout << std::endl;
infoLogger->logMessage(LogLevel::WARNING, "This is a warning message.");
std::cout << std::endl;
infoLogger->logMessage(LogLevel::ERROR, "This is an error message.");