在下面的代码中,我有抽象类 TestAlgModule
我将向图书馆用户展示,他们可以使用多种功能,例如 VOLUME, MIXER
等等。但是,假设用户需要一个仅在 MixerManager
中添加的新功能。那么我需要在 TestAlgModule
中添加它抽象类,现在突然所有派生类都需要添加它而没有任何好处。
我该如何避免这种情况?
#include <iostream>
using namespace std;
enum {VOLUME, MIXER, UNKNONWN};
class TestAlgModule {
public:
virtual void open(int type) = 0;
virtual void close(int type) = 0;
};
class volumeManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
};
class mixerManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
void differentFunction() {};
};
/* users calls this to get algModule and then call functions to get the job done */
TestAlgModule *getTestAlgModule(int type) {
switch(type) {
case VOLUME:
return new volumeManager();
case MIXER:
return new mixerManager();
default:
break;
}
return nullptr;
}
int main() {
TestAlgModule * test = getTestAlgModule(MIXER);
test->open();
//test->differentFunction(); this can't be called as it is not part of abstract class and users are exposed only abstract class
return 0;
}
如果有不清楚的地方请告诉我,我会尽力回答。我正在寻找一种更好的方法来做到这一点,即更改
VolumeManager
应该独立于 MixerManager
.
最佳答案
如果你想使用抽象工厂,就像你在上面的代码中所做的那样,那么你需要返回一个指向基类的指针。那是对的。然后您需要通过基指针调用所有函数。
顺便说一句,请不要使用原始指针。请使用std::unique
而是指针。
有 2 种可能的解决方案。
将接口(interface)函数作为非纯函数,但仍然是虚拟函数添加到您的基类,并具有默认行为。
virtual void differentFunction() {}
由于其他纯函数,基类仍然是抽象的。这可能会导致胖接口(interface)。但在许多情况下,这是一个可以接受的解决方案。
第二种可能性是使用
dynamic_cast
将基类指针向下转换为所需的指针。并检查动态转换的返回值。if(mixerManager* mm = dynamic_cast<mixerManager*>(test)) {
mm->differentFunction();
}
所有这一切当然取决于整体设计和您想要实现的目标。但以上2个是标准模式。
还有其他可能满足您需求的设计模式,例如构建器或原型(prototype)。请检查。
关于c++ - 避免不必要地添加抽象函数以适应新功能的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62056212/