我有一个如下的类层次结构:
struct Arg {
Info someSpecificInfo;
OtherInfo anotherInfo
}
class BaseEvaluator {
public:
BaseEvaluator (Info info) {};
virtual Result evaluate();
}
class SpecificEvaluator1 : public BaseEvaluator {
public:
Derived(Info info): Base(info) {};
Result evaluate();
}
class SpecificEvaluator2: public BaseEvaluator {
public:
SpecificEvaluator2(Info info): Base(info) {};
Result evaluate();
}
然而,我目前需要实现两个特定的Evaluator
类。其中一个使用Info对象(本质上是另一个SpecificEvaluator3
类(。但是,另一个Evaluator
需要整个Arg
对象。
现在我知道,对于OOP,我不应该混合这两个类,本质上我应该将BaseEvaluator
更改为InfoEvaluator
,并创建另一个ArgEvaluator
类,也许这两个都可以从具有evalute()
方法的BaseEvaluator
基类继承。
然而,问题是,对于这两个Evaluator
类,它们在很大程度上使用相同的辅助方法,其中这些辅助方法使用Info成员变量。我可以将我的两个Evaluator
类可视化如下:
class ArgSpecificEvaluator {
public:
ArgSpecificEvaluator (Arg arg) {};
Result evaluate(); // Implementation Uses OtherInfo
protected:
void helperMethod1(Info);
void helperMethod2(Info);
}
class SpecificEvaluator3 : BaseEvaluator {
public:
SpecificEvaluator3(Info info): {};
Result evaluate();
protected:
void helperMethod1(Info);
void helperMethod2(Info);
}
正如您所看到的,helperMethods1有重复的代码。由于对于ArgSpecificEvaluator
,当我们直接使用arg.Info
而不是仅使用info
作为参数时,helper方法是相同的。在这种情况下,该如何调和呢?
对于所有类,我是否切换为仅使用Arg
?我之所以不这么做,是因为SpecificEvaluator
类甚至不需要触摸OtherInfo
。SpecificEvaluator3
是一种特殊情况,它肯定是一种评估器,但具有ArgSpecificEvaluator
的特性,因为它们都使用相同的辅助方法。最初,helperMethods((应该没有参数,并使用成员变量Info
,但这种情况更难协调,所以我决定将其抽象并放入参数中。
在某种程度上,我想要实现的是从基类继承的SpecificEvaluator3
的Java等价物,但实现了一个带有helper方法的接口。我如何在C++中处理这个问题?多重继承?
我认为你想要实现的要么是这样的:
class ArgSpecificEvaluator : public SpecificEvaluator3 {
public:
ArgSpecificEvaluator (Arg arg) : Base(arg.info) {};
Result evaluate() override; // Implementation Uses OtherInfo
}
class SpecificEvaluator3 : BaseEvaluator {
public:
SpecificEvaluator3(Info info): {};
virtual Result evaluate();
protected:
void helperMethod1(Info);
void helperMethod2(Info);
}
或者
class Helper {
protected:
Helper(Whatever youneed);
void helperMethod1(Info);
void helperMethod2(Info);
}
class ArgSpecificEvaluator : public BaseEvaluator, protected Helper {
public:
ArgSpecificEvaluator (Arg arg) {};
Result evaluate() override; // Implementation Uses OtherInfo
}
class SpecificEvaluator3 : public BaseEvaluator , protected Helper {
public:
SpecificEvaluator3(Info info): {};
Result evaluate() override;
}
注意,我将ArgSpecificEvaluator
设置为也继承基本BaseEvaluator
,因为它具有相同的evaluate
功能。
一般来说,我试图绕过继承的漏洞,将一个公共类的实例作为成员,而不是继承一个类。
class Helper {
public:
Helper(Whatever youneed);
void helperMethod1(Info);
void helperMethod2(Info);
}
class ArgSpecificEvaluator : public BaseEvaluator {
public:
ArgSpecificEvaluator (Arg arg) {};
Result evaluate() override; // Implementation Uses OtherInfo
protected:
Helper helper;
}
class SpecificEvaluator3 : public BaseEvaluator {
public:
SpecificEvaluator3(Info info): {};
Result evaluate() override;
protected:
Helper helper;
}
我想,对所有类使用Arg
,并且在某些情况下没有值或默认值,这可能也是一个不错的解决方案。