1

何よりも、読んでくれてありがとう!

C++ でアプリケーションを開発していますが、設計上の問題についてアドバイスが必要です。説明させてください:

アプリケーションのメイン クラスにはいくつかのコレクションがありますが、他のクラスは最終的にそれらのコレクションの 1 つから値を取得する必要があります。このようなもの:

class MainClass { 
private:
   // Collections are internally implemented as QHash
   Collection<Type1> col1;
   Collection<Type2> col2;
};
class RosterUnit {
public:
   RosterUnit() {
      /* This method needs to get a specific value from col1 and
         initialize this class with that data */
   }
};

class ObjectAction {
public:
    virtual void doAction() = 0;
};

class Action1 : public ObjectAction {
public:
    void doAction() {
       // This needs a specific value from col2
    }
};

class Action2 : public ObjectAction {
public:
    void doAction() {
       // This needs a specific value from col1
    }
};

私の最初のアプローチは、必要に応じてコレクション全体をパラメーターとして渡すことでしたが、2 つのコレクションを渡す必要があり、後で ObjectAction の別のサブクラスを作成し、他のオブジェクトから要素を取得する必要がある場合、ObjectAction サブクラスにはあまり適していません。コレクション (col3 と仮定) の場合、すべての ObjectAction サブクラスの doAction() シグネチャを変更する必要がありますが、これはあまり柔軟ではないと思います。また、Dialog があり、そこから RosterUnit を作成したいとします。RosterUnit を作成するためだけに、コレクションをダイアログに渡す必要があります。

次に、コレクションを指す RosterUnit と ObjectAction で静的変数を使用することにしましたが、その解決策にはあまり満足していません。柔軟性が足りないと思います。

私は設計パターンについて読んでいて、最初はget関数を備えたSingletonが良い選択だと思っていましたが、さらに調査した後、それは私の場合には適切な設計ではないと思います. グローバル変数を使用すると、より簡単になり、多かれ少なかれ同じになりますが、これは正しい方法ではないようです。

では、アドバイスをお願いできますか?

どうもありがとうございました!

4

3 に答える 3

0

ここでは、何をしようとしているのかについて十分な情報がありません。「将来のある時点で、この静的に作成されたアクションには、取り残されたこのデータが必要になる」ように聞こえます。それはどのように意味がありますか?たとえば Future や Callable を使用する場合のように、 dataを使用してアクションを構築するか、コマンドに次のデータを要求させるかのいずれかです。この場合、ワーク キューを実装するだけです。

スレッドプールのようなことをしようとしているようです。これらのアクションが何らかの形で関連している場合、テンプレート メソッドパターンのようなものを実装する構成オブジェクトが必要です。他の方法は (プロトコルの施行) でなければなりません。

于 2012-05-06T00:58:39.107 に答える
0

おそらくイテレータを使用したいでしょう。それらは、特定のコンテナからシーケンスを抽象化する目的で正確に存在します。

最初にイテレータを必要とするコードにイテレータを渡す方法が問題である場合は、グローバルを使用する誘惑に屈しないでください。パラメータを渡す必要がある場合は、より複雑に見えるかもしれませんが、コードはそれに対してはるかに分離されています。このトピックについて詳しく知りたい場合は、「依存性注入」が適切なキーワードです。

また、ObjectAction から継承する代わりに、std::function または boost::function をチェックすることをお勧めします。関数型スタイルは、Java などの言語で通常行われている方法とは対照的に、最新の C++ でより一般的になっています。

于 2012-05-05T22:19:35.100 に答える
0

前述のように、イテレータはコレクションの詳細を抽象化するのに適しています。しかし、このルートに進むことは、イテレータを使用するオブジェクトがコレクションの内容を知る必要があることを意味します。つまり、必要なコレクション内のオブジェクトを決定する方法を知る必要があるため、結合が増加します。(詳しくは、以下の Factory の段落で説明します) これは、検討する必要があるものです。

もう 1 つの方法は、MainClass に、ある種のキーを受け取り、コレクション (findObject(key)) からオブジェクトを返すアクセサ メソッドを作成することです。内部的に、MainClass メソッドはコンテナーを検索し、適切なオブジェクトを返します。ただし、このアプローチを使用するには、前述のように依存性注入によって MainClass にアクセスするか、場合によってはそれをシングルトンにする必要があります (ただし、このシナリオではお勧めしません)。

これまでに提供された情報を使用すると、ObjectAction ファクトリが MainClass への参照を持ち、ObjectAction 作成ロジックの一部として、適切な MainClass アクセサーを呼び出して結果を ObjectAction に渡す方が良い場合もあります。 MainClass からの ObjectAction オブジェクト。

于 2012-05-06T09:36:48.260 に答える