4

私には2つの機能があります:

public void WithdrawMoney()
{
    //Take money from bank account
    //Exceptions abort the operation and are printed
    //Rethrow exception if called by TransferMoney()
}

public void TransferMoney()
{
    //Take money from one account and only deposit on another account if no exceptions were caught in WithdrawMoney()
    WithdrawMoney(); 
    DepositMoney();     
}

私が欲しいのは、 TransferMoney()によって呼び出された場合にのみ、WithdrawMoney()で発生した例外を再スローできるようにすることです。アカウントからお金を引き出したいだけの場合は、例外を処理する必要がありますが、別の方法で呼び出されていないため、再スローする必要はありません。

boolsでの作業に加えて、私の頭に浮かぶ別の解決策があります。スタックトレースを調べて、TransferMoney()がWithdrawMoney()を呼び出したかどうかを確認し、呼び出した場合にのみ例外を再スローします。または、メソッドで例外が発生したかどうかを確認する方法はありますか?

例外をスローする前に、catchブロックで例外がスロー可能かどうかを確認できるかどうかを知りたいだけです。常にスローする場合、WithdrawMoney()を直接呼び出すと、例外は処理されません。

4

4 に答える 4

4

追跡や文書化が難しい任意の条件があるため、メソッドの動作が異なることはありません。

内部で使用する引き出しメソッドの部分をリファクタリングして、外部から使用するメソッドと内部から使用するメソッドを取得する必要があります。

private void MakeWithdrawal() {
    //Take money from bank account
    //Exceptions abort the operation
}

public void WithdrawMoney()
{
    MakeWithdrawal();
    //Exceptions are printed
}

public void TransferMoney()
{
    //Take money from one account and only deposit on another account if no exceptions were caught in WithdrawMoney()
    MakeWithdrawal();
    DepositMoney();     
    //Exceptions are printed
}
于 2012-09-02T10:41:50.957 に答える
3

ラッパーを追加するだけです。単一責任はメソッドにも適用されます。

private void WithdrawMoney()
{
    // Take money from bank account

    // _Always_ Rethrow 
}

public void WithdrawMoneyPublic()
{
   // call WithdrawMoney and handle the exceptions
}
于 2012-09-02T10:34:37.807 に答える
2

関数呼び出しにオプションのパラメーターを追加することを検討できます。

public void WithdrawMoney(bool throwOnError = false)
{
    //Do stuff
    catch(Exception ex)
    {
        if(throwOnError) throw;
    } 
    //Do stuff
}

public void TransferMoney()
{
    WithdrawMoney(true);
}

ただし、これは、記述してはならないコードの例として、「フレームワーク設計ガイドライン」から抜粋したものです。素晴らしい本です。

于 2012-09-02T11:09:26.907 に答える
1

なぜ例外なのか?

なぜあなたは(おそらく両方の)メソッドが成功を示すブール値を返すようにしないのですか?

あなたはboolsのアイデアを持っていたようですが、何らかの理由でそれを実現しませんでした。なんでそんなことないの?とても論理的でシンプルです!

出金は内部例外を処理し、falseを返します。これは、TransferMoneyもチェックしてfalseを返します。また、操作が成功したかどうかをこれらの操作で返すようにすることも非常に論理的です。

public bool WithdrawMoney()
{
    //Take money from bank account

    //Exceptions abort the operation and are printed, and return false

    //Flawless run returns true
}

public bool TransferMoney()
{
    //Take money from one account and only deposit
    //    on another account if WidthdrawMoney returned true
    if (WithdrawMoney())
    {
        DepositMoney();     
        return true;
    }

    return false;
}

結局のところ、2番目のWithdrawMoney操作が失敗しなかったことを確認する必要があります。失敗した場合は、1番目のWithdrawMoneyで行った変更をロールバックします。

于 2012-09-02T10:56:47.997 に答える