- This is a behavioral design pattern.
- The basic idea behind this pattern is that a request or a command passes through a chain of objects until it is handled.
- Objects involved in this pattern are of two types. Processing Objects and Command Objects.
- Processing objects handle the commands given by command objects.
- Each processing object knows what it can handle and passes the command to the next member in the chain if not handled.
- A common example to understand this pattern better is the C++ exception handling mechanism. Unhandled exceptions are passed up the call stack until somebody acts upon it.
EXAMPLE: Demonstrate the chain of responsibiltiy behavioral pattern
#include <iostream>
using namespace std;
// STATES
enum ErrorStates { ANALYZE=0, FIX, VERIFY, CLOSE };
// Command Class
class ErrorReport {
private:
ErrorStates state;
public:
ErrorReport(ErrorStates state) {
this->state = state;
}
ErrorStates GetState() {
return state;
}
void SetState(ErrorStates state) {
this->state = state;
}
};
// General base class for all processing objects
class Error {
protected:
ErrorStates state;
Error* successor;
public:
Error(ErrorStates aState) { state = aState; }
void SetSuccessor (Error* error) {
this->successor = error;
}
virtual void ProcessError(ErrorReport& report) = 0;
};
// Processing object class 1 for state ANALYZE
class AnalyzeError : public Error {
public:
AnalyzeError() : Error(ANALYZE) {};
void ProcessError(ErrorReport& report) {
if ( report.GetState() == ANALYZE ) {
cout << "AnalyzeError::Handled the command to analyze the error ..." << endl;
}
else {
cout << "AnalyzeError::Passing to my successor ..." << endl;
successor->ProcessError(report);
}
}
};
// Processing object class 2 for state FIX
class FixError : public Error {
public:
FixError() : Error(FIX) {};
void ProcessError(ErrorReport& report) {
if ( report.GetState() == FIX ) {
cout << "FixError::Handled the command to fix the error ..." << endl;
}
else {
cout << "FixError::Passing to my successor ..." << endl;
successor->ProcessError(report);
}
}
};
// Processing object class 3 for state VERIFY
class VerifyError : public Error {
public:
VerifyError() : Error(VERIFY) {};
void ProcessError(ErrorReport& report) {
if ( report.GetState() == VERIFY ) {
cout << "VerifyError::Handled the command to verify the error ..." << endl;
}
else {
cout << "VerifyError::Passing to my successor ..." << endl;
successor->ProcessError(report);
}
}
};
// Processing object class 4 for state CLOSE
class CloseError : public Error {
public:
CloseError() : Error(CLOSE) {};
void ProcessError(ErrorReport& report) {
if ( report.GetState() == CLOSE ) {
cout << "CloseError::Handled the command to close the error ..." << endl;
}
else {
cout << "VerifyError::No successor ... ignore" << endl;
cout << "No action required ..." << endl;
}
}
};
int main()
{
// Create instances for processing objects
AnalyzeError* analyzeError = new AnalyzeError();
FixError* fixError = new FixError();
VerifyError* verifyError = new VerifyError();
CloseError* closeError = new CloseError();
// Create the chain of responsibility
analyzeError->SetSuccessor(fixError);
fixError->SetSuccessor(verifyError);
verifyError->SetSuccessor(closeError);
// Issue command 1
cout << "--------------- o/p for command 1 ----------------" << endl;
ErrorReport* errorReport1 = new ErrorReport(ANALYZE);
analyzeError->ProcessError(*errorReport1);
// Issue command 2
cout << "--------------- o/p for command 2 ----------------" << endl;
ErrorReport* errorReport2 = new ErrorReport(CLOSE);
analyzeError->ProcessError(*errorReport2);
// Cleanup
delete errorReport2;
delete errorReport1;
delete closeError;
delete verifyError;
delete fixError;
delete analyzeError;
}
OUTPUT:
--------------- o/p for command 1 ----------------
AnalyzeError::Handled the command to analyze the error ...
--------------- o/p for command 2 ----------------
AnalyzeError::Passing to my successor ...
FixError::Passing to my successor ...
VerifyError::Passing to my successor ...
CloseError::Handled the command to close the error ...
0 comments:
Post a Comment