该项目有一个目标:使用以界面为中心的设计。基本上,我们声明只有公共纯函数的类,并让真正的类继承自它们。
现在出现了一个问题——如何重用效用函数?
这是一个例子:
class InterF1 {
public:
int f1() = 0;
int g1() = 0;
};
class InterF2 {
public:
int f2() = 0;
};
class C1: public InterF1 {
public:
int f1();
int g1();
};
class C2: public InterF1, InterF2 {
public:
int f1();
int g1();
int f2();
};
在实现 C1::f1() 和 C2::f1() 时,我看到这两个函数之间的代码重复。我应该如何删除重复?
以下是我的想法:
1)我可以像这样向接口类添加保护:
class InterF1 {
public:
int f1() = 0;
int g1() = 0;
protected:
int util();
int convenient_var_calculated_by_util;
};
在上述设计中,C1::f1() 和 C2::f2() 都可以调用 util()。
2)我可以抽象一个新接口:
class UtilI {
public:
int util(int in_var) = 0;
};
在本设计中,InterF1、C1 和 C2 更改为
class InterF1 {
public:
int f1(UtilI u) = 0;
int g1() = 0;
};
class C1: public InterF1 {
public:
int f1(UtilI u);
int g1();
};
class C2: public InterF1, InterF2 {
public:
int f1(UtilI u);
int g1();
int f2();
};
C1::f1() 和 C2::f1() 都调用 UtilI API。
解决方案 2 似乎更符合我们的“以界面为中心”的目标,而且看起来确实更好。但我有一个担心,InterF1 和 InterF2 本身应该是比 UtilI 更高级别的抽象,它更多的是实现细节,我是否混合了 2 个级别?换句话说,如果稍后实现更改,我将需要再次更新 f1() 和 f2() 签名,这听起来不对。
解决方案 1 看起来确实很方便,但对我来说它看起来不那么“纯粹”,我在这里是不是太教条了?