0

このトピックに関するいくつかの質問を見てきましたが、最も基本的な例を超えて、try/catch ブロックを最適に使用する方法が根本的に欠けていると思います。

この特定のケースでは、単純なものからかなり複雑なものまで、問題を解決するための一連のテクニックがあり、私が念頭に置いているのは次のようなものです。

if ($zombie_killer -> board_with_nail == 'failed') {
    if ($zombie_killer -> machette == 'failed') {
       if ($zombie_killer -> shotgun == 'failed') {
           $this -> panic;
       }
    }
}

しかし、その代わりに、try/catch ブロックを使用する方が良いアプローチかもしれないと考えたので、カスタム サブプロセスを追加する余地が増えました。たとえば、手法が機能しなかった理由をログに記録したり、"a" を反映するように UI を更新したりします。通常の保留時間よりも長い」などです。だから私はそれが次のようなものになると思います:

try {
    $zombie_killer -> board_with_nail;
}
catch(Exception $e) {
    try {
        $zombie_killer -> machette;
    }
}

しかし、これはあまり気分が良くありません。他の人が「if/else と try/catch のどちらが良いか」で得たすべての反論を考えると、少なくとも大きな違いとそれらを使用する理由があることは明らかです。 . 私がこのユースケースについて質問している理由は、try/catch で処理するのが最善だと思うからです。これに正しくアプローチします。

4

3 に答える 3

0

try/catch の哲学は、あなたが説明したものではありません。これを使用する良い方法は、発生したエラーに応じてさまざまな例外をキャッチすることです。例えば:

try {
    $value = readDatabase();
    writeDatabase($++value);
} catch (ReadErrorException $e) {
    // do something
} catch (WriteErrorException $e) {
    // do something
}

探しているものを実現したい場合は、さらにコードが必要ない場合は、 and を使用するだけで簡単に実行できます。その場合は、elseif を使用してください。

たとえば、コードは次のようになります。

if (
    $zombie_killer -> board_with_nail == 'failed'
    && $zombie_killer -> machette == 'failed'
    && $zombie_killer -> shotgun == 'failed'
) {
    $this -> panic;
}

また、ブール値を属性として使用するのも良い方法です。

if (
    !$zombie_killer -> board_with_nail
    && !$zombie_killer -> machette
    && !$zombie_killer -> shotgun
) {
    $this -> panic;
}

編集:他の回答に関するコメントを読んだ後

あなたが言ったことに基づいて、別の解決策を提案します。$zombie_killer がクラスであることを理解すると、kill() などの名前の public メソッドを作成できます。このメソッドは、クラスのパブリック、プライベート、および保護された属性にアクセスできます。

最初に例外なく例を書きます。

クラスの内部:

public function kill()
{
    if ($zombie_killer -> board_with_nail != 'failed') return true;
    if ($zombie_killer -> machette != 'failed') return true;
    if ($zombie_killer -> shotgun != 'failed') return true;

    return false;
}

他のファイルでは、私たちが話していたもの:

if (!$zombie_killer->kill()) {
   $this->panic;
}

ご覧のとおり、コードはよりクリーンで、関数のデフォルトの動作はゾンビが殺されないことを想定しており、例外的なケースは、ゾンビを殺すために使用されるメソッドの 1 つが成功した場合です。これは、私たちが通常考える方法とは逆です。ゾンビを殺すことができると仮定し、例外的なケースは、すべてが失敗した場合です。しかし、これは単なる哲学的な問題であり、コードを逆にすることができ、それでも機能します。

例外も含めて見てみましょう。

クラスファイル:

public function kill()
{
    if (
        $zombie_killer -> board_with_nail == 'failed' 
        && $zombie_killer -> machette == 'failed'
        && $zombie_killer -> shotgun == 'failed'
    ) {
        throw new NotKilledException();
    }
}

その他のファイル:

try {
    $zombie_killer->kill();
} catch (Exception $e) {
    $this->panic;
}

ご覧のように?この場合、例外バージョンはあまり役に立ちません。ネストされた if を実行する必要があるためです。条件は、3 つの異なるタイプの kill を達成する必要があるためです。例外は、ゾンビを殺さないことです。例外的なコード $this->panic を実行したいからです。

次に、どの種類の実装がより適しているかを選択する必要があります。どちらも正しく、開発者はどちらも正しいと考えます。ただし、最初のものを選択します。単純なコピーペーストで、ゾンビキラーにさらに多くの殺害タイプを追加でき、読みやすくなります。

于 2012-08-07T10:04:12.150 に答える
0

個人的な見解としては、if/else とは異なり、try/catch はユースケースではなく例外を処理するためにあるので、状況に応じてやりたいことを処理するためではなく、そのために使用する方がよいと思います。

于 2012-08-07T10:05:33.597 に答える
0

例外は、条件ステートメントを表す代替方法ではありません。例外は、まくらでゾンビを殺そうとするような例外的な状況です。

function kill_zombie($weapon) {
    if (!$weapon instanceof FireArm && !$weapon instanceof HeavyObject)
        throw new Exception("Zombies can only be killed with firearms and heavy objects");
    // ...
}
于 2012-08-07T10:13:54.357 に答える