ソフトウェアに「万が一」などない

最近、ソフトウェア開発において「万が一」という言葉を耳にする機会が残念ながら増えてしまったので、その辺りについて自分なりの見解を書いておこうと思います。

まっとうなエンジニアなら気安く万が一とか言うなよな!常識だよな!みたいな話です。

ソフトウェア開発に万が一などない

厳密に言うとこれは間違いです。(大ブーメラン)

自動車や医療機器など、フェイルセーフが強く求められるような製品に搭載されるソフトウェアに関しては、この考えは概ね正解でしょう。

極端な話、機器が動作している途中に例外が発生したからといって、いきなり製品の動作を停止してしまうようではマズいということ。

e-words.jp

問題は、この考えがふつうのPCやスマホのアプリ、WEBアプリ等にも適用されてしまう場合です。

「万が一」は問題のスコープを曖昧にしてしまう

例えば、Windowsフォームアプリのメニューについて

  • レジストリに保存された、インストール時に指定されたソフトウェアのモードを見て、非管理モードだった場合は設定用ダイアログの表示メニューをグレーアウトして出せないようにする

という処理をしているとしましょう。

この時、設定用画面のApplyボタン(設定を保存するボタン)に

  • 万が一、何らかの手違いで非管理者モードでこのダイアログが表示できてしまっても、Applyボタンを押した時に設定を保存しないように条件分岐させる

という実装がされてしまうと、エンジニアにとって非常に困ったことになります。

具体的には、

  • 本来レジストリとは何の関係もないはずの設定用ダイアログクラスにレジストリをチェックする機構が埋め込まれてしまう。
  • テストを書くのが死ぬほど面倒になる(ダイアログを表示している途中で明示的にレジストリを書き換えるような処理が必要)
  • レジストリの状態を2つのオブジェクトが同時に管理することになり、中途半端なクラスが出来上がる
  • ていうかテストでレジストリいじるっておかしくない?

レジストリは頻繁にいじくりまわすような代物ではないので、起動時のみレジストリの値をチェックしてあとはControllerのフィールドにreadonlyで置いておく、みたいな方が個人的にはしっくりきます。

一応、何でこんな発想になるのかは想像できます。

  • 万が一設定の書き換えができてしまうとデグレということで検証やら何やらしなくちゃいけなくなるから最終的にエラーが出ないようにする

要は誰も内部処理をちゃんと分かってないので、臭いものにフタをするみたいな発想です。最高に虚無ですね。

何が言いたいかというと、そういった値のチェックはしかるべきフェーズで実装されなければならず、それを守らないというのであればクラス間の責務が曖昧になり、テストを書くことが難しくなるということです。

結局のところ、実装が難しくてメンテがしづらいテストは地獄ということでしょうか。

それでも万が一、

どうしてもチェックしたいというのであれば、メニュー画面から設定用ダイアログの項目をクリックした瞬間に内部で保持していたインストールモードを見に行って、非管理者モードだったら何も表示しない、という処理を実装した方がだいぶマシでしょう。readonlyフィールドが勝手に書き換えられることがあればの話ですが。

そういうわけで

まっとうなエンジニアのみんなは問題のスコープをしっかり見極めてちゃんとテスト管理してコードの質を上げていこうな!

僕からは以上です。