多个程序共享的插件/模块

时间:2013-03-13 13:55:32

标签: c++ oop design-patterns plugins

我想为我的程序定义类似插件的插件。他们应该是这样的:

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,我将不得不实施 Prog1ViewProg2ViewProg3View作为SystemViewForSpecificModule接口的具体实现。

此外,我必须考虑以下情况:

Prog2将嵌入Prog1 ,我希望能够这样做:

  1. 实例化SpecificModule实例
  2. 运行调用SpecificModule::doSpecificTask();
  3. 的prog1部分
  4. 运行同时调用SpecificModule::doSpecificTask();
  5. 的prog2部分

    我的问题是:如何在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之外的其他解决方案)?

0 个答案:

没有答案