0

私はかなり厄介なソフトウェア設計の問題に直面しており、それはかなり長い間私を悩ませてきました。問題は、オブジェクトの初期化であり、それを実現するために多くのゲッターが使用されます。多くのゲッターとセッターが通常、デザインが悪いことを示している理由について、AllenHolub[1]の記事に出くわしました。この設計の問題についても説明している他の記事を以下にいくつかリストしました。

今私の問題について。私は現在、流体シミュレーションに取り組んでいます。流体のシミュレーションに関連する関数と変数を含むSimulationクラスがあります。最初、このクラスには、シミュレーションのタイムステップを実行するtimeStep()というパブリック関数が1つしかありませんでした。ここで、いくつかのよく知られたフローをシミュレートしたいと思います。それらをシナリオとして見ることができます。これは通常、シミュレーションを正しく初期化することになります。たとえば、私はテイラー-グリーン渦流を持っています。シミュレーションは、特定のフローをシミュレートしていることを知る必要はありません。シミュレーションアルゴリズムを実行するだけでよいので、別のクラスTaylorGreenVortexを作成しました。クラスTaylorGreenVortexは、Taylor-Green渦流に対応するようにシミュレーションを初期化する必要があります。ここで問題が発生します。Taylor-Green渦流の初期化方程式には、シミュレーションでも必要とされる多くの変数が必要であるため、そのクラスに存在します。その結果、これらの変数を取得するために、Simulationクラスに多くのゲッターを追加しました。ただし、これらすべてのゲッターによってSimulationクラスが非常に公開され、SimulationとTaylorGreenVortexの間に高い結合度が生成されるため、これも望ましくありません。さらに、初期化子(TaylorGreenVortex)が最初にSimulationオブジェクトを作成して関連する変数を取得し、後でSimulationオブジェクトの他の変数をリセットしてTaylor-Green渦流をシミュレートすることも厄介です。その結果、これらの変数を取得するために、Simulationクラスに多くのゲッターを追加しました。ただし、これらすべてのゲッターによってSimulationクラスが非常に公開され、SimulationとTaylorGreenVortexの間に高い結合度が生成されるため、これも望ましくありません。さらに、初期化子(TaylorGreenVortex)が最初にSimulationオブジェクトを作成して関連する変数を取得し、後でSimulationオブジェクトの他の変数をリセットしてTaylor-Green渦流をシミュレートすることも厄介です。その結果、これらの変数を取得するために、Simulationクラスに多くのゲッターを追加しました。ただし、これらすべてのゲッターによってSimulationクラスが非常に公開され、SimulationとTaylorGreenVortexの間に高い結合度が生成されるため、これも望ましくありません。さらに、初期化子(TaylorGreenVortex)が最初にSimulationオブジェクトを作成して関連する変数を取得し、後でSimulationオブジェクトの他の変数をリセットしてTaylor-Green渦流をシミュレートすることも厄介です。

私はいくつかの解決策について考えましたが、これらの解決策のすべてが実際に問題を解決するわけではなく、単に問題を別のクラスにシフトするか、設計をさらに悪化させます。たとえば、「情報エキスパート」パターンに従う場合は、TaylorGreenVortexクラスを削除し、そのすべての機能をSimulationクラスに移動する必要があります。ただし、シミュレーションが多くの異なるフローをサポートする必要がある場合、これによりシミュレーションクラスがかさばります。TaylorGreenVortexとSimulationの両方に必要な変数を持つある種のDataクラスを導入することもできますが、SimulationとTaylorGreenVortexがDataから変数を取得できるように、このDataクラスに多くのゲッターを追加する必要があります。クリーンなソリューションのためのあなたの提案は何ですか?問題に関連する特定のデザインパターンを知っている場合は、上記の状況でどのように適用できるか、具体的に説明していただけますか?前もって感謝します。

  1. http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html
  2. http://martinfowler.com/bliki/GetterEradicator.html
  3. http://pragprog.com/articles/tell-dont-ask
4

2 に答える 2

2

より良いアドバイスをするには、コードを見る必要があると思いますが、説明からはビルダーが必要なようです。しかし、TaylorGreenVortexあなたが説明したクラスはビルダーの仕事をしているように見えるので、あなたが探しているものではないかもしれません. シミュレーションを処理するクラスと、そのシミュレーションをさまざまなシナリオを表すように構成する方法を知っているさまざまなビルダー クラスを持つ IMHO は、優れた設計です。まず、シミュレーションに必要なすべてのパラメーターを受け取るコンストラクターをSimulationクラスに配置し、特定のシミュレーションのニーズに応じて、特定の各ビルダーにコンストラクター引数を渡します。パラメータが多すぎる場合は、モデル化していないものがあると考えることができます。Simulationクラスには複数の責任があります ( SRPを参照)。その場合、クラスをリファクタリングしたいかもしれませんがSimulation、コードを見ないとわかりません:(。スニペットをいくつか投稿していただけますか?

HTH

于 2012-12-20T12:44:06.737 に答える
0

私は主題やあなたのデザインについてあまり知らないので、あなたが達成しようとしていることについて完全にコメントすることはできません(もっとスニペットをお願いします)が、状態Simulation)を1つに保持しようとしているようです場所とその状態 ( ) をどうするか、そして 2 つが相互作用する必要がTaylorGreenVortexFlowあるときにそれらを分離するのに問題があります。

Simulation共通オブジェクトからの継承という考えを完全に捨てましたか? timeStep()Taylor-Green Vortex Flow 中に何が起こるかを反映するように関数をオーバーライドしますか? 適切な参照渡しがないために Java を使用している場合、これが唯一の賢明なオプションかもしれません。

于 2012-12-20T12:57:17.220 に答える