
同僚がコードに関するメールを送ってきました。彼はtry/catch
を使ってビジネスロジックを駆動することを避けようとしています。
問題はtry/catch
ではなく、それは単に問題の症状に過ぎません。問題を見つけることができますか?いくつかの仮定を立てる必要がありますが、私と同じ結論に達すると信じています。
コードは以下の通りです。無実の人を守るために変更しました:
private Customer GetOrCreateCustomer(long customerTelephoneNumberOrCustomerId)
{
Customer customer;
try
{
customer = this.DoMagic(customerMasterTelephoneNumberOrCustomerId);
}
catch (DataException)
{
try
{
//TODO: I know this isn't ideal. Still thinking of a better way to do this.
customer = this. GetCustomer(customerMasterTelephoneNumberOrCustomerId);
}
catch (DataException)
{
customer = this.GetCustomerFromExternal(customerMasterTelephoneNumberOrCustomerId);
customer.CustomerId = this.CreateCustomer(customer);
}
}
return customer;
}
このシステムには、nullは悪いものだという根本的な哲学があります。nullが生成される可能性があるほとんどのケースで例外がスローされます。最初は、これに問題があるとは思いませんでした。アーキテクチャの決定、美学として捉えていましたが、コードとやり取りしていくうちに、これがアーキテクチャ上の間違いであることが明らかになりました。
なぜnullの場合に例外をスローすることが悪いのか、と疑問に思うかもしれません。
例外をスローすることを検討する際のガイドラインを以下に示します:
- 例外をスローするためにnullをチェックしなければならないという事実は、それが必要ないことのヒントになるはずです。それは予期される結果であり、したがって例外ではありません。
- 例外をスローすることは、.Netで実行できる最もリソース集約的な操作の一つです。
例外
はまさにその通り、例外です。それはコードで行われた仮定に対する例外であり、これらの仮定が破られた場合、システムは終了しなければならず、システムが未知の状態にあるため(つまり、データベースが利用できなくなった)続行できません。これは攻撃ベクトルにもなり得ます。- 例外をスローするということは、ビジネスルールを強制するために上流の呼び出しを
try/catch
ブロックで囲む必要があることを意味します。null値は、アプリケーションのフローを制御するビジネス機会です。null値に対するアクションは、ビジネス決定を行う必要がある時点で実行されるべきです。例えば、customer変数がnullの場合、UIレイヤーでユーザーにID ‘1234’の顧客が見つからないことを示すメッセージが表示されます。
著者:Chuck Conwayはソフトウェアエンジニアリングと生成AIを専門としています。ソーシャルメディアで彼とつながりましょう:X (@chuckconway) または YouTube をご覧ください。