4

友達と争っています。

彼は私にこのコードを言った:

method SetBalance(balance) {
    if (balance > 0) {
        this.balance = balance;
        return true;
    }
    return false;
}

これよりも優れています:

method SetBalance(balance) {
    if (balance < 0) {
        throw new InvalidArgumentException("Balance couldn't be negative")
    }
    this.balance = balance; 
}

私の質問は、「検証にはどちらのアプローチが適しているか」です。なぜ?

ありがとうございました。

4

6 に答える 6

6

ああ。ステータスと例外を返します。

例外を無視することはできないので、私は例外をスローすることを好みます。プログラムがクラッシュするか、明示的にキャッチして処理する必要があります。

返品ステータスは無視してかまいません。

その上、これが現代のプログラミングに例外が存在する理由ではありませんか?対処するために、まあ...例外(バランス<= 0、起こるべきではない何か)。

于 2012-08-10T08:07:35.230 に答える
1

セッターの場合、開発者はこれらのメソッドからの戻り値を期待することはありません。これは、とにかく値の設定を処理すると考えているためです。
例外がある場合、これは何かが本当に間違っていることを理解し、コードをもう一度処理するのに役立ちます。
の代わりにruntime exception、のように独自の例外を定義InvalidBalanceExceptionし、このメソッドが署名自体でこの例外をスローするように指定することをお勧めします。これにより、テストフェーズでの驚きを回避し、開発フェーズ自体でビジネスロジックを決定します。

于 2012-08-10T08:12:27.177 に答える
1

戻り値は簡単に無視されます。ここに明確なコーディングバグがあるので、大声でクラッシュします。プログラムを停止/セグメンテーション違反/停止することもあります-例外はまだキャッチされる可能性があります。私たちは「理想的な世界」に住んでいますが、幸運でない同僚を想像してみてください。彼らは、根本的な原因に対処できないエラーシグナリング機能をギャグするために行く可能性があります(より複雑なエラーシナリオをここに挿入してください)。クライアントに間違った方法で物事を行う方法を与えない場合、コーディングははるかに簡単になります。

于 2012-08-10T08:17:52.563 に答える
0

私の個人的な意見:どちらのアプローチにも用途があります。それは、状況が発生した理由、それを防ぐことができるかどうか、クライアントがそれを防ぐために何をすることができたかによって異なります。

サーバ:

method SetBalance(int balance)
{
   // do something only if balance >= 0
}

クライアント:

myServer.SetBalance(balance);

ケース1: 状況は、どこか(サーバーまたはクライアント)のバグが原因でのみ発生します。例外をスローします。責任者にコードを修正させます。

ケース2: 外部依存関係から不正な入力を受け取った。クライアントは簡単に前提条件を確認できます。例外をスローします。クライアントがそれに不満を持っている場合は、クライアントにコードを修正させます。

if(balance>0)
  myServer.SetBalance(balance);
else
  //take appropriate action.

ケース3: 外部依存関係から不正な入力を受け取った。クライアントは前提条件を簡単に確認できませんでした。例:クライアントが文字列を解析する必要があります。これはサーバーの仕事です。ここで、サーバーが成功を返す必要があることは理にかなっています。

bool succeeded = myServer.SetBalance(balance);
if(!succeeded)
  //take appropriate action.

私の答えを書き留めた後、私はそれがすべてこれに要約されることに気づきました:クライアントはメソッドSetBalanceを呼び出すためにtry-catchを使用する必要はないはずです。(これはバグなので、例外をキャッチしたり、前提条件を自分で確認したり、戻り値を調べたりしないでください)

これは関連する主題に関する良い読み物です:http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

編集: ジョジョは良い点を述べています。失敗する可能性がある場合は、メソッドの名前をTrySetBalance()に変更します。

于 2012-08-10T08:48:55.817 に答える
0

すでに与えられた答えに加えて、「setFoo」という名前の関数でブール値を返すことは非常に誤解を招きます。ブール値を変換すると、yes/noが思い浮かびます。したがって、ブール値をoopで返す関数は、答えとしてyes / noを与える質問として読み取り可能である必要があります(例:isBalanceSet)。

同僚との話し合いで、通常のセッターの唯一の有効な戻り値は、fluent-interfacesのクラス自体であると考えました。

あなたの質問に関しては、クラスが実際にそのプロパティ自体を検証する場合、例外をスローする方が良い解決策です;)

于 2012-08-10T08:29:16.880 に答える
0

例外処理は、実行時エラーであろうと論理エラーであろうと、OOPのエラーを処理するために選択される方法です。例外処理を正当化するための議論の1つは、エラーコードが使用された場合、関数のクライアントがエラーコードのチェックを忘れて、簡単に見つけられない可能性のある潜在的なバグにつながる可能性があるということです。一方、例外処理を使用すると、キャッチされなくても、処理されるまで伝播します。したがって、OOPの純粋主義者は、常に例外処理を使用してアドバイスします。

于 2012-08-21T12:55:51.593 に答える