c++ - 避免不必要地添加抽象函数以适应新功能的设计模式

标签 c++ oop design-patterns

在下面的代码中,我有抽象类 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/

相关文章:

c++ - 从 txt 文件中读取并删除第一行(或最后一行)而不复制

c++ - Bamboo CppUnit 测试解析器报告没有测试

c++ - 如何加载 Apache2 模块的依赖项(外部库)?

javascript - 设置间隔() : How to stop then start itself again?

c++ - 类的初始化没有匹配的构造函数

用于匹配逗号分隔单词的优先级顺序的 XSD 模式

C++绘制矩形位置

class - 为什么可以修改 Raku 类的只读数组属性?

java - 在枚举结构上循环时重构和删除 case 语句

iphone - 构建 iPhone/iPad 应用程序 View