11

私は次の難問に直面しています。私たちのソフトウェアには、アルゴリズムオブジェクトの抽象的な基本クラスがあります。これらのオブジェクトにはすべて、次のような共通のexecute()メソッドがあります。

class Algorithm
{
public:
  // [...]
  virtual void execute() = 0;
  // [...]
};

実装するアルゴリズムごとに、基本クラスから継承し、ロードされたすべてのアルゴリズムオブジェクトを中央の場所に格納するだけです。ここまでは順調ですね。

問題は現在、アルゴリズムのパラメータにあります。アルゴリズムごとに、(外部クラスによって)設定する必要のあるパラメーターを記述できるようにする必要があります。この目的のために、各アルゴリズムParameterListにそのパラメーターを含むオブジェクトを与えました。私たちにとって、パラメータはある種のタイプ(などint)とラベル(「反復回数」など)で構成されていることを明確にする必要があります。

ParameterList問題は、ある種のGUIに接続したいときに始まります。明らかに、私たちのアルゴリズムには、使用しているグラフィカルAPI(Qt、GTKなど)の「知識」があってはなりません。ただし、同じ側で、たとえばアルゴリズムにファイル名が必要であることを指定することにより、アルゴリズムパラメータを意味的に記述できるようにする必要があります。このファイル名がどのように表示されるかは、GUI次第です。

ParameterListこれをある種のセマンティックタイプの知識と組み合わせる方法はありますか?

この質問は非常に曖昧に聞こえます。ただし、重要なコード例を投稿することは許可されていません(NDAの理由により)。それで、過去に誰かが同様の問題に直面したことがありますか?

まとめ:GUIの正確な詳細を知らなくても、オブジェクトがGUIに必要なパラメーターを記述できるようにします。

4

1 に答える 1

9

ここでの1つのオプションは、ビジターパターンを使用することです。次のような基本クラスを作成できます。

class Parameter {
public:
    virtual ~Parameter() {} // Polymorphic classes need virtual dtors.

    virtual void accept(ParameterVisitor& v) = 0;
};

次のようなサブクラスを定義できます。

class IntParameter: public Parameter {
public:
     virtual void accept(ParameterVisitor& v) {
          v.visit(*this);
     }
};
class FilenameParameter: public Parameter {
public:
     virtual void accept(ParameterVisitor& v) {
          v.visit(*this);
     }
};

accept各メンバー関数で、のタイプは*thisクラスの静的タイプであることに注意してください。つまり、IntParameter&最初のケースとFilenameParameter&2番目のケースです。

ParameterVisitor次に、次のように基本クラスクラスを定義できます。

class ParameterVisitor {
public:
    virtual ~ParameterVisitor() {} // Polymorphic classes need virtual dtors.

    virtual void visit(IntParameter& p) {}
    virtual void visit(FilenameParameter& p) {}
    /* .. etc. .. */
};

次に、この訪問者をサブクラス化して、タイプ情報を取得できます。

class Gui1ParameterVisitor: public ParameterVisitor {
public:
    virtual void visit(IntParameter& p) {
        /* ... use GUI1 to create a field for an integer. */
    }
    virtual void visit(FilenameParameter& p) {
        /* ... use GUI1 to create a field for a filename. */
    }
};

class Gui2ParameterVisitor: public ParameterVisitor {
public:
    virtual void visit(IntParameter& p) {
        /* ... use GUI2 to create a field for an integer. */
    }
    virtual void visit(FilenameParameter& p) {
        /* ... use GUI2 to create a field for a filename. */
    }
};

これParameterListで、クラスはのリストを保存できParameter*ます。visit次に、適切な訪問者タイプをインスタンス化し、そのコールバックにすべてのウィジェット構築を実行させることにより、GUIを構築できます。これにより、タイプセーフになり、必要な情報が回復されます。新しいパラメータタイプを作成するたびvisitに、ParameterVisitorクラスに新しいメンバー関数を追加する必要があるという欠点がありますが、すべてのGUI構築を行うには、とにかくそれを行う必要があります。

お役に立てれば!

于 2012-05-15T19:32:42.587 に答える