简体   繁体   English

责任链模式C ++

[英]Chain of responsibility pattern C++

I am studying designs patterns. 我正在研究设计模式。 I'm not sure about how to implement the chain of responsibility pattern in C++. 我不确定如何在C ++中实现责任链模式。 I am using the Argo tool to generate my code from my diagram 我正在使用Argo工具从图表生成代码 在此处输入图片说明 .

In this diagram, the Oracle class is a "client". 在此图中,Oracle类是“客户端”。 The Oracle.cpp constructor method has the next lines Oracle.cpp构造函数方法具有以下几行

#include "Oracle.h"
Oracle::Oracle(){
    Validation v;//Here
}

Here I get the "error: 'Validation' was not declared in this scope". 在这里,我得到“错误:在此范围内未声明'Validation'”。 My question: Is it necessary to create a UML relation "dependency" from Oracle to Validation? 我的问题:是否有必要创建从Oracle到Validation的UML关系“依赖关系”? Or how will I be able to fix this error? 或者我将如何解决该错误?

Your Oracle class should not have a member of type Validation, but a member of type Handler instead. 您的Oracle类不应具有Validation类型的成员,而应具有Handler类型的成员。

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). 现在有两个选择,要么允许Oracle类知道链将如何运行,要么可以自己构建链(带有所有依赖项)。 Or you need a builder class to build the chain and inject it to the Oracle instance (preferably trough the constructor). 或者,您需要一个构建器类来构建链并将其注入到Oracle实例中(最好是通过构造器)。

The second option follows the philosophy of the CoR pattern best (the user of the chain is unaware of its inner working). 第二种选择最好地遵循CoR模式的原理(链的用户不知道其内部工作)。

Maybe ArgoUML added that link to validation to be able to create an instance of a Handler, but it is weird. 也许ArgoUML在验证中添加了该链接,以便能够创建Handler的实例,但这很奇怪。

Further, I believe that the method setNext does not belong to the Oracle class. 此外,我相信setNext方法不属于Oracle类。 This class does need a reference to the first Handler object of the chain, but that is best set from the constructor. 此类确实需要引用链中的第一个Handler对象,但这最好从构造函数中进行设置。 If set trough a setter, you should give it a proper name like setHanlderChain to make the purpose clear. 如果通过设置器设置,则应给它一个适当的名称,例如setHanlderChain,以使目的明确。

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) 对于您来说,这可能看起来像这样(请注意,自从我用C ++编写任何重要文章以来已经有很长时间了,并且我认为类图中的顺序是执行的顺序)

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. 对于第二个问题,我没有实际的示例,但是:如果将此方法放在构建器类(例如,OracleHandlerChainBuilder)中,则仅该类必须导入所有这些步骤,而oracle类则必须仅导入Handler。

Where you create your Oracle instance, you set its chain (with setNext in your case) to the result of the build method. 在创建Oracle实例的地方,将其链(在本例中为setNext)设置为build方法的结果。 The class that will instantiate the Oracle class needs to import both the Oracle class and the OracleHandlerChainBuilder class. 实例化Oracle类的类需要同时导入Oracle类和OracleHandlerChainBuilder类。

This way, dependencies between classes is minimized. 这样,可以最大程度地减少类之间的依赖关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM