我正在研究设计模式。我不确定如何在C ++中实现责任链模式。我正在使用Argo工具从我的图表生成我的代码。
在此图中,Oracle类是“客户端”。 Oracle.cpp构造函数方法有下一行
#include "Oracle.h"
Oracle::Oracle(){
Validation v;//Here
}
这里我得到“错误:'验证'未在此范围内声明”。我的问题:是否有必要创建从Oracle到验证的UML关系“依赖”?或者我将如何解决此错误?
答案 0 :(得分:1)
您的Oracle类不应该具有Validation类型的成员,而应该是Handler类型的成员。
那当然会在某处设置验证(我认为这将是链条的第一步)。
现在你仍然需要建立链条,链条的步骤不应该知道其他步骤。
现在有两个选项,要么允许Oracle类知道链是如何运行的,它可以自己构建它(带有所有依赖性)。 或者您需要一个构建器类来构建链并将其注入Oracle实例(最好是通过构造函数)。
第二个选项遵循CoR模式的理念(链的用户不知道其内部工作)。
也许ArgoUML添加了验证链接,可以创建一个Handler实例,但这很奇怪。
此外,我认为方法setNext不属于Oracle类。这个类确实需要对链的第一个Handler对象的引用,但最好从构造函数中设置。 如果通过setter设置,你应该给它一个正确的名称,如setHanlderChain,以明确目的。
成功
回复评论:
责任链的一个要素不知道链本身,它只是一个参与者。 因此,您需要创建链:实例化参与者并设置下一步。
对于您的示例,这可能看起来像这样(请注意,自从我在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;
}
对于你的第二个问题,我没有现实生活中的例子,但是: 如果将此方法放在构建器类(例如OracleHandlerChainBuilder)中,则只有该类必须导入所有这些步骤,并且oracle类必须仅导入Handler。
在创建Oracle实例的位置,将其链(在您的情况下使用setNext)设置为构建方法的结果。将实例化Oracle类的类需要导入Oracle类和OracleHandlerChainBuilder类。
这样,类之间的依赖关系就会最小化。