@nqounetです。
「架空ECサイトで学ぶ決済審査システム」シリーズの第2回です。
シリーズ全体の目次はこちらをご覧ください。
前回は、金額上限チェックと有効期限チェックの2つの審査条件を実装しました。
今回は、審査条件が増えてコードが複雑化する問題を体験します。
注意: このシリーズで扱う決済システムは学習用の架空システムです。実際の決済システムを開発する際は、PCI DSS などのセキュリティ基準を遵守してください。
ペルマートの要件追加
ペルマートの開発は順調に進み、サービスが成長してきました。それに伴い、セキュリティ強化のため新しい審査条件が次々と追加されることになりました。
追加される審査条件は以下の通りです。
- ブラックリストチェック: 不正利用が確認されたカードを拒否
- 残高(利用枠)確認: 決済金額が利用可能枠を超えていないかチェック
- 不正利用検知: 短時間での連続決済を検知
「簡単簡単、if文を追加すればいいんでしょ?」と思いますよね。やってみましょう。
審査条件を5つに増やす
既存の2つに加えて、3つの審査条件を追加します。
| |
コードを見て気づくこと
動作はしますが、コードを見てどう思いますか?
問題1: ネストが深い
if-else のネストが5段階になっています。新しい条件が追加されるたびに、既存のコードの中にさらにif文を追加していく必要があります。
| |
問題2: 審査順序の変更が困難
「ブラックリストチェックを最初にしたい」という要件変更が来たらどうでしょう?コード全体を書き換える必要があります。
問題3: 個別のテストが困難
「残高確認だけをテストしたい」と思っても、その前の3つのチェック(金額上限、有効期限、ブラックリスト)を通過するテストデータを用意しなければなりません。
早期リターンで書き直してみる
「ネストが深いのは書き方の問題では?」と思った方、素晴らしい観察力です。早期リターンで書き直してみましょう。
| |
ネストは解消されました!しかし、まだ問題があります。
残る問題点
問題1: 1つの関数に全ての審査ロジックが集中
check_payment 関数が50行を超えています。審査条件が10個になったら100行以上になるでしょう。
問題2: 新ルール追加時の影響範囲
新しい審査条件を追加するたびに、この巨大な関数を編集する必要があります。既存のロジックを壊してしまうリスクがあります。
問題3: 再利用性がない
「金額上限チェックだけ別の場所で使いたい」と思っても、この関数から切り出すのは大変です。
問題4: 審査条件ごとのテストが書きにくい
例えば「不正利用検知だけをテストしたい」場合、前の4つのチェックを全て通過するテストデータを用意する必要があります。
| |
これは面倒ですし、テストデータの準備を間違えると、何をテストしているのかわからなくなります。
まとめ
- 審査条件が増えるとif文のネストが深くなる
- 早期リターンでネストは解消できるが、根本的な問題は残る
- 1つの関数に全ロジックが集中すると保守が困難になる
- 個別の審査条件をテストしにくい
- 審査順序の変更や新ルール追加が大変
次回予告
ペルマートの決済審査コードは、このままでは保守困難です。審査条件は今後も増えていくでしょう。
次回は、この問題を解決するために、各審査ロジックを独立した「チェッカー」クラスに分割します。オブジェクト指向の力を借りて、拡張性のある決済審査システムを完成させましょう。
完成コード
この回の「問題を体験する」ためのコードです。次回で改善していきます。
| |
