0

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 enter image description here.

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?

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
Juan
  • 2,073
  • 3
  • 22
  • 37
  • Did you include the Validation.h to the Oracle.cpp ? – Deamonpog Feb 14 '13 at 02:57
  • 1
    Seems your question is specifically about using ArgoUML, and not about the chain of responsibility pattern. Maybe you should change the title. – Ergwun Feb 14 '13 at 02:57
  • @Deamonpog not I not include Validation.h in Oracle because that will modify the UML diagram of the pattern Chain of Responsability. – Juan Feb 14 '13 at 02:59
  • @Ergwun I think that this question is independent of Tool. – Juan Feb 14 '13 at 03:01
  • Then there will be no way for Oracle.cpp to get the datatype name `Validation` and will keep giving the compilation error. Auto generated code nomaly is like this :P. at least put something like `class Validation;` on the top. – Deamonpog Feb 14 '13 at 03:02
  • Then a diagram for this pattern implement in C++ is different because I always will need add *.h (in this case Validation.h) in the client class (i.e dependency UML relation) – Juan Feb 14 '13 at 03:17
  • Then a diagram for this pattern implement in C++ is different? because I always will need add *.h (in this case Validation.h) in the client class (i.e dependency UML relation) – Juan Feb 14 '13 at 03:46
  • If you need Validation class instance in Oracle constructor, then that should be shown in the diagram, no? Why is it there? – hyde Feb 14 '13 at 05:07

1 Answers1

1

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.

Glenner003
  • 1,450
  • 10
  • 20
  • please you will be explain "Or you need a builder class to build the chain and inject it to the Oracle instance (preferably trough the constructor).". I am new using this patterns. – Juan Feb 14 '13 at 12:55
  • Have you any example of this pattern in C++ with multiple files?. – Juan Feb 14 '13 at 15:44