GoTheDistance

ござ先輩と言われています。(株) クオリティスタートという会社をやっています。

変更には追加で対応する

会社にあった日経SYSTEMS8月号を拾い読みして、改めて"変更すること"を考えた。

今動いているものを保証するコスト

新規開発と仕様変更や新規要求に伴う既存ソースの変更。最も異なる点は「既存機能の動作保証をやらねばならないこと」にある。修正が必要になれば当然その影響範囲を正確に把握せねばならない。大規模システムだとコレはなかなか骨の折れる作業になるし、漏れがあってはたまらない。

If文をひとつ加えるだけなんだけど影響範囲がでかくて大変なものもあれば、工数は2週間かかるけど現行システムには影響無い修正もあると思う。修正コストと修正の影響範囲のマトリックスを作るとこの関係がよくわかる。私ならスコープが局所化出来る後者の方が圧倒的に気楽です。

変更でなく、追加で対応する

仕様変更に対応する最適の方法は「ソースの変更でなく、追加で対応する」だと思う。これは基本的にはインターフェースに実装するという設計になっていないと辛い。例えば課金プランの追加に伴い、それを新たな課金ポリシーとして実装して欲しいという要望があるとする。

Goodな設計ならば「課金する」というのがインターフェースとして抽出されていて、それをImplして新たな課金アルゴリズムを作ることが可能になる。既存には手を加えず新たな実体をDIでブチ込んで対応することが出来る。

これがマズい設計になると、課金ロジックがメソッド単位にまとめられてしまい、新たな分岐ロジックを追加しないと対応出来ない。インターフェースを抽出とかやると大改造になりかねないのでパッチを当てるような修正しか現実的に出来そうにない。修正反映後、既存も含めて再テストやりたくないけどやるしかねーって感じだろう。

また、修正したら違う修正をやらなくなったという連鎖を起こし始めたら、かなり細かくキッチリバージョン管理しないと痛い目を見る。ここで武器になるのがPOJOなユニットテスト可能な資産だと思うわけだ。ビジネスロジックを自動テストでvalidate出来るっていう目に見えないメリットは大きい。

大雑把に言えばこんな感じだが、大体あってると思う。

追加で対応するためには、インターフェースに対して実装する仕組みにするのが汎用的に使えて良い。デサパタもそんなのが多いし。みんなインターフェースがあってそれをごにょごにょして違うパターンを作り出してるだけじゃん。そこが腕の見せ所なんだろうな。もっと優れた設計ポリシーはあるんだろうけど、これをやるだけで全然違うはず。やってから次を求めればよかばい。

新たに追加するだけの10行と、1000行の中に変更で追加する10行。アウトプットが同じなら、どちらが大変ですかということです。