12

複雑なオブジェクト構成によって駆動される Java でコーディングされた複雑なエンタープライズ アプリケーションに取り組んでいます。例: 特定のシナリオで、アクションを実行するには、次のフローがあります。

login() -> 
Followed by defined sequence of 10 to 20 method calls in different classes -> 
Followed by a logout()

フレームワーク内では、ログイン、ログアウト、および 10 ~ 20 のメソッド呼び出しの多くを含むほとんどすべてのアクションに戻り値の型がありません。誤った動作は、フレームワークによって処理されます。ログインで言う

public void login(){
try{
 //login actions
 //chained sequence of calls

}catch(){
 // framework handling exceptions and other rollback options
}
}

中間の 10 から 20 のアクションは、フレームワークの階層のさまざまなレベルにあるさまざまなオブジェクトに対するメソッド呼び出しです。

ランダムなクラスは次のようになります。

class someobject{

def variable

void action1(){ do something on variable }
void action2(){ do something on variable }
...
}

変数は頻繁に状態を変更し、これらのアクションにはフレームワークによってのみ定義されたシーケンスがあり、非常に面倒です。

おそらく、これらのメソッドのすべてまたは少なくともいくつかの適切な戻り値の型があれば、たとえば の場合のブール値のようにlogin()、人生はずっと楽になるでしょう。一連の void を返す関数にこのように厳密に準拠しているため、フローを理解するためにデバッグするのが難しく、単体テストも悪夢のようになりました。

そのため、特に一連のアクションが関与する場合は、何かを返す関数を作成する方が常に良いという印象を受けています。それで、これは安全な推定ですか?これについてご意見を伺いたいです。私が間違っている場合は修正してください。

4

5 に答える 5

10

メソッドの最も基本的なテスト可能性は、その戻りコードによるものです。loginあなたが(あなたが指摘したように)あなたが現在ログインしているかどうかをテストできるようにする必要がある場合、リターンbooleanは明らかな方法です. それ以外の場合は、不必要に非アトミックで複雑に見えるいくつかのプロパティをチェックする必要があります (ただし、他の理由で必要になる場合があります)。

私にとって、この議論はあらゆる意味のある方法にまで及びます。リターン コードを使用するvoidことはかなり一般的ですが、設計上の理由というよりは、古い習慣の結果です。ただし、単純なプロパティ セッターは反例であり、他にもあると確信しています。

于 2012-04-26T10:55:00.703 に答える
2

メソッドがクラス内のローカル データを操作する場合、クラスのコンテキストで意味のある「動作」をモデル化している限り、void メソッドは完全に合理的です。たとえば、内容を並べ替える SpecialSortedList がある場合、つまり myList.sort() の場合、sort() メソッドは SpecialSortedList に関連付けられた動作をモデル化するため無効になります。

メソッドがクラス内のローカル データを操作しない場合、つまり、パラメーターを介してデータを受け取り、データの一部を返す (つまり、ローカル データに依存しない) 場合、それを static として宣言し、さらにそれをユーティリティまたはヘルパー クラス。

于 2012-04-26T10:57:51.933 に答える
2

私の意見では、一連のアクションで常に何かを返す必要はありません。それは完全に要件に依存します。つまり、ログイン認証メソッドでは、単純化のためにブール値の結果を返す方が適切です。アクションのチェーンが互いに独立している場合、私の意見では、アクションで使用されないものを返す必要はありません。したがって、あるアクションの結果が次のアクションに影響する場合は、単純化とテストのために何かを返す必要があるため、問題を引き起こしているメソッドの出力から直接抽出できます。メソッドが特定されると、特定された特定のメソッドを確認できます。したがって、基本的にすべてが要件に依存します。何かを返さずに要件をより適切に処理できる場合は、それを使用する必要があります。また、ベスト プラクティスやデザイン パターンに従って効率を高める必要があります。これにより、すべての状況でより優れた結果が得られ、最終的に混乱を避けることができます。それは私の意見です。

于 2012-04-26T11:03:21.247 に答える
0

ますます、void ではなくステータス コードのようなものを返すようになっています。これはいくつかのことを行います:

  1. 関数を呼び出したコードが次に何をすべきかを認識できるようにします (たとえば、操作が失敗した場合、呼び出し元のコードは、操作が成功した場合とは異なることを行う必要がある場合があります)。
  2. テストとデバッグが簡単です(あなたが言及したように)。私は、テスト容易性のためにコードを書くことが、コードの品質を確保するための最良の方法の 1 つであると信じ始めています (もちろん、実際にテストすることを前提としています)。void 関数はテストが困難です。

私の好みは、可能な限り、ほとんどの関数がパラメーターを取り、答えを返し、クラス変数を変更しないようにすることです。Jaco が述べたように、これらは静的に宣言でき、ユーティリティ クラスに移動することもできます。次に、値を返す関数をいくつかのコントローラー関数で使用することができます。

于 2013-09-13T18:41:47.247 に答える
-2

私は答えを2つの部分に分けます:

  • 「void」を返すと便利な場合 -

    メソッドが不正な状態/例外を示すためだけに値を返す場合は、"void" を返す必要があります。例外は、「ブール値」の戻り値を言うのではなく、すべてのエラー シナリオを処理する必要があります。ここで、呼び出しコードはブール値と例外の両方を再度検証する必要があります。例外のみをスローした場合は、呼び出し元のコードがはるかに簡単で明確になります。

  • void があまり役に立たない場合 -

    メソッドが何らかの操作を実行し、結果として値を返す場合、「void」は返されるべきではなく、関連する結果の型 (ブール値/整数/オブジェクトなど) が返される必要があります。

一般に、戻り値は、メソッドが何かを返すかどうかに実際に対応する必要があります。メソッドが正しく実行されたかどうかに対応するべきではありません (そうであるはずです)。すべての入力検証/例外シナリオは、対応する例外をスローすることによって処理する必要があります。例: 入力が無効な場合、メソッドが実行されなかったことを示す「ブール値」を返すのではなく、IllegalArgumentException をスローします。

于 2014-09-15T07:52:28.657 に答える