2

プログラム用にプラグインのようなオブジェクトを定義したいと考えています。それらは次のようになります。

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();
};

実装と複雑さを隠すために、モジュールがファサード Interface を介して基礎となるシステムを認識できるようにします。

class SystemViewForSpecificModule
{
public :
   virtual SystemData& getData(//some parameters) = 0;
   virtual void doSystemAction1() = 0;
   virtual void doSystemAction2() = 0;
   ...
};

SpecificModule最後に、モジュールおよび/またはインスタンスを処理できるいくつかのプログラムを作成できるようにしたいと考えています。

prog1、prog2、および prog3 があることを考えると 、インターフェイスの具体的な実装としてProg1ViewおよびProg2Viewを実装する必要があります。Prog3ViewSystemViewForSpecificModule

さらに、次のケースを考慮する必要があります。

Prog2 は Prog1 を埋め込みます。私はこれを実行できるようにしたいと考えています。

  1. インスタンスをインスタンス化SpecificModuleする
  2. 呼び出しを行う prog1 部分を実行しますSpecificModule::doSpecificTask();
  3. も呼び出すprog2部分を実行します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 - セッターを使用してシステム ビューを指定する

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このソリューションのもう 1 つの悪い点は、メソッド ( や などinit())のシステム ビューにアクセスできないことですfinalize()。そして明らかに、それらをサブクラスに移動すると、継承の関心が低下します。

この例の場合、どのソリューションを使用しますか?

4

0 に答える 0