12

アルゴリズムをクラスにカプセル化することはどのように (一般的ではない) のだろうか? より具体的には、相互に共通のパラメーターを転送するいくつかの個別の関数を使用する代わりに、次のようにします。

void f(int common1, int param1, int *out1);
void g(int common1, int common2, int param1, int *out2)
{
  f(common1, param1, ..);
}

共通パラメーターをクラスにカプセル化し、コンストラクターですべての作業を行います。

struct Algo
{
  int common1;
  int common2;

  Algo(int common1, int common2, int param)
  { // do most of the work }

  void f(int param1, int *out1);
  void g(int param1, int *out2);
};

関数の引数を介して共通のパラメーターと中間結果を転送する必要がないことは非常に実用的だと思われます..しかし、この「パターン」が広く使用されているのを見たことがありません..考えられる欠点は何ですか?

4

6 に答える 6

5

この問題に対処する設計パターンがあります。それは「戦略設計パターン」と呼ばれます -ここでいくつかの良い情報を見つけることができます.

「ストラテジー」の優れた点は、アルゴリズムのファミリーを定義し、アルゴリズムを使用するクライアントを変更することなく、それらを交換可能に使用できることです。

于 2008-09-30T17:00:37.170 に答える
5

決して悪い戦略ではありません。実際、自分の言語 (C++ で行う) に、基礎となる機能への不透明なインターフェイスを定義する何らかのタイプの抽象スーパークラスを定義する機能がある場合、実行時にさまざまなアルゴリズムを入れ替えることができます (並べ替えアルゴリズム、例えば)。選択した言語にリフレクションがある場合は、無限に拡張可能なコードを使用することもでき、アルゴリズムのコンシューマが作成されたときには存在すらしていなかったアルゴリズムをロードして使用できます。これにより、他の機能クラスとアルゴリズム クラスを緩やかに結合することもできます。これは、リファクタリングに役立ち、大規模なプロジェクトで作業するときに正気を保つのに役立ちます。

もちろん、複雑なクラス構造の構築を開始するときはいつでも、追加のアーキテクチャ (したがってコード) を構築して維持する必要があります。しかし、私の意見では、長期的に見れば、この小さな不便さを上回るメリットがあります。

最後の提案:コンストラクターで作業を行わないでください。コンストラクターは、クラスの内部構造を適切な既定値に初期化するためにのみ使用する必要があります。はい、これには初期化を完了するために他のメソッドを呼び出すことが含まれる場合がありますが、初期化は操作ではありません。探していた特定のアルゴリズムを実行するためにコード内でもう 1 回呼び出す必要がある場合でも、この 2 つを分離する必要があります。

于 2008-09-30T17:06:35.703 に答える
2

あなたの質問は、「ソフトウェアの主なアイデアがアルゴリズムを実行することだけである場合、オブジェクト指向設計をどのように使用すればよいですか?」のように、より一般的に表現できますか?

その場合、ご提示いただいたような設計が第一歩としては良いと思いますが、これらは問題依存であることが多いです。

良い一般的なデザインは、そこにあるようなものだと思います。. .

class InputData {};
class OutputData {};

class TheAlgorithm 
{
private:
     //functions and common data

public:
   TheAlgorithm(InputData);      
   //other functions
   Run();
   ReturnOutputData();
};

次に、必要に応じて main() または GUI と対話させます。

于 2008-09-30T17:08:54.187 に答える
1

おそらく、(何かが欠けていない限り) より良いアプローチは、アルゴリズムをクラスにカプセル化し、メソッド呼び出しを介して実行させることです。コンストラクターを介してすべてのパラメーターをパブリック プロパティに渡すか、アルゴリズムを含むクラスに渡されるすべてのパラメーターをカプセル化する構造体を作成できます。しかし、通常、そのようなコンストラクターで実行することはお勧めできません。何よりもまず、直感的ではないためです。

public class MyFooConfigurator
{
   public MyFooConfigurator(string Param1, int, Param2) //Etc...
   {
      //Set all the internal properties here
      //Another option would also be to expose public properties that the user could
      //set from outside, or you could create a struct that ecapsulates all the
      //parameters.
      _Param1 = Param1; //etc...
    }

    Public ConfigureFoo()
    {
       If(!FooIsConfigured)
          return;
       Else
          //Process algorithm here.
    }
}
于 2008-09-30T17:07:07.917 に答える
1

私は通常、アルゴリズムをカプセル化するためにファンクターまたは関数オブジェクトを作成します。

私は通常、次のテンプレートを使用します

class MyFunctor {
    public:
       MyFunctor( /* List of Parameters */ );
       bool execute();
    private:
       /* Local storage for parameters and intermediary data structures */
}

次に、ファンクターを次のように使用しました。

    bool success = MyFunctor( /*Parameter*/ ).execute();
于 2008-09-30T17:02:38.193 に答える
0

コンストラクターのパラメーターを使用して両方のメソッドを呼び出す必要がある場合は、それを行います。

同じパラメーターで両方のメソッドを呼び出す必要がない場合は、そうしません。

于 2008-09-30T16:59:07.953 に答える