Reputation: 2103
I am studying designs patterns. I'm not sure about how to implement the chain of responsibility pattern in C++. I am using the Argo tool to generate my code from my diagram .
In this diagram, the Oracle class is a "client". The Oracle.cpp constructor method has the next lines
#include "Oracle.h"
Oracle::Oracle(){
Validation v;//Here
}
Here I get the "error: 'Validation' was not declared in this scope". My question: Is it necessary to create a UML relation "dependency" from Oracle to Validation? Or how will I be able to fix this error?
Upvotes: 0
Views: 1759
Reputation: 1552
Your Oracle class should not have a member of type Validation, but a member of type Handler instead.
That will off course be set to a Validation somewhere (I assume this will be the first step of the chain).
Now you still have to build the chain, the steps of the chain should not be aware of other steps.
There are two options now, either the Oracle class is allowed to know how the chain will operate an it may build it itself (with all the dependencies that incurs). Or you need a builder class to build the chain and inject it to the Oracle instance (preferably trough the constructor).
The second option follows the philosophy of the CoR pattern best (the user of the chain is unaware of its inner working).
Maybe ArgoUML added that link to validation to be able to create an instance of a Handler, but it is weird.
Further, I believe that the method setNext does not belong to the Oracle class. This class does need a reference to the first Handler object of the chain, but that is best set from the constructor. If set trough a setter, you should give it a proper name like setHanlderChain to make the purpose clear.
Success
In reply to the comments:
An element of a chain of responsibility has no knowledge about the chain itself, it is just a participator. So somewhere you need to create the chain: Instantiating the participators and setting their next step.
For you example this might look like this (mind you it has been a long time since I wrote anything serious in C++, and I assumed that the order in your class diagram is the order of execution)
Handler buildOracleChain()
{
CalculePR step6 = new CalculePR();
step1.setNext(null);
SolutionKE step5 = new SolutionKE();
step5.setNext(step6);
CalculeSP step4 = new ValcvuleSP();
step4.setNext(step5);
KeyGeneration step3 = new KeyGeneration();
step3.setNext(step4);
Encrypt step2 = new Encrypt();
step2.setNext(step3);
Validation step1 = new Validation();
step1.setNext(step2);
return step1;
}
For your second question, I have no real life example but: If you put this method in a builder class (OracleHandlerChainBuilder for instance), only that class has to import all those steps and the oracle class has to import Handler only.
Where you create your Oracle instance, you set its chain (with setNext in your case) to the result of the build method. The class that will instantiate the Oracle class needs to import both the Oracle class and the OracleHandlerChainBuilder class.
This way, dependencies between classes is minimized.
Upvotes: 1