我想为我的程序定义类似插件的插件。他们应该是这样的:
class ModuleBase
{
public :
void baseFunction1();
void baseFunction2();
...
virtual void init() = 0;
virtual void finalize() = 0;
};
class SpecificModule : public ModuleBase
{
public :
virtual void doSpecificTask() = 0;
};
因此我将使用SpecificModule实现:
class ConcreteSpecificModule1 : public SpecificModule
{
public :
void init();
void finalize();
void doSpecificTask();
};
为了掩盖实现和复杂性,我希望我的模块通过Facade接口看到底层系统:
class SystemViewForSpecificModule
{
public :
virtual SystemData& getData(//some parameters) = 0;
virtual void doSystemAction1() = 0;
virtual void doSystemAction2() = 0;
...
};
最后,我希望能够创建几个可以处理Module和/或SpecificModule
实例的程序。
考虑到我有prog1,prog2和prog3,我将不得不实施
Prog1View
,Prog2View
和Prog3View
作为SystemViewForSpecificModule
接口的具体实现。
此外,我必须考虑以下情况:
Prog2将嵌入Prog1 ,我希望能够这样做:
SpecificModule
实例SpecificModule::doSpecificTask();
SpecificModule::doSpecificTask();
我的问题是:如何在SpecificModule实例中将引用(或指针)传递/存储到系统中?
1 - 在施工时存储参考:
因此,SpecificModule接口应该
class SpecificModule : public ModuleBase
{
SystemViewForSpecificModule& m_sys;
public :
SpecificModule(SystemViewForSpecificModule& sys):m_sys(sys){}
virtual void doSpecificTask() = 0;
};
这是实现我的问题的一种愉快的方式,但是不要忘记在prog2中我首先要这样做 使用prog1运行我的模块,因此在这种情况下我必须动态地从SystemViewForSpecificModule实现切换。
我们可以认为使用引用不是一个好的解决方案,或使用类似的东西:
class SystemView : public SystemViewForSpecificModule
{
SystemViewForSpecificModule* concreteSystem;
public
SystemView(SystemViewForSpecificModule& sys)
{concreteSystem = &sys;}
void setSystem(SystemViewForSpecificModule& sys)
{concreteSystem = &sys;}
void doSystemAction1()
{concreteSystem->doSystemAction1();}
...
}
这样,模块甚至不知道实现已经改变 但是,我担心由于额外的vtable访问会降低性能。
2 - 使用setter指定系统视图
SpecificModule接口应该是:
class SpecificModule : public ModuleBase
{
SystemViewForSpecificModule* m_sys;
public :
setSystem(SystemViewForSpecificModule& sys){m_sys = &sys;}
virtual void doSpecificTask() = 0;
};
这似乎是一个方便的解决方案,但我不喜欢该模块的事实:
3 - 传递对SpecificModule方法的引用
至少SpecificModule
界面看起来像这样:
class SpecificModule : public ModuleBase
{
virtual void doSpecificTask(SystemViewForSpecificModule& sys) = 0;
};
我不喜欢将相同的引用10000次传递给同一个函数(prog1和prog2部分都会调用很多次)。
此解决方案的另一个不利之处是:我无法访问ModuleBase
方法(例如init()
和finalize()
)中的系统视图。显然,将它们移动到子类会降低继承的兴趣。
在这个案例中你会使用什么解决方案(我希望看到除了提出的3之外的其他解决方案)?