C++ 设计模式之责任链模式

发布于:2024-07-01 ⋅ 阅读:(16) ⋅ 点赞:(0)

C++ 设计模式之责任链模式

简介

1、责任链模式 (Chain of Responsibility):为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2、责任链模式 (Chain of Responsibility)应用场景包括但不限于:
2.1、当有多个对象可以处理同一个请求时,具体哪个对象处理该请求由运行时刻自动确定。
2.2、当你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求时。
2.3、当你想在不必指定具体接收者的前提下,向一个或多个对象发出请求时。

3、责任链模式 (Chain of Responsibility)的构成
3.1、抽象处理者(Handler):定义一个处理请求的接口,包含一个处理请求的抽象方法和一个指向下一个处理者的引用。

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):实现抽象处理者的方法,判断能否处理请求,如果能够处理请求则进行处理,否则将请求传递给下一个处理者。

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、定义

// 日志级别常量
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、实现

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、调用

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.");

网站公告

今日签到

点亮在社区的每一天
去签到