「担保」という概念

皆様、最近いかがお過ごしでしょうか?
暑すぎて、PCの過熱が心配な杉本です。

 

今回は、システム開発や、簡単なプログラム作成における「担保」の概念について考えてみたので、諸々書いてみます。

 

「担保」とは?

言葉のまんまなのだが、
「前提条件を満たしている場合には、同一条件で常に同じ結果であり」
「前提条件を満たしていない場合には、想定した結果に収束する」
この2つが確実に成立させる事を言う。

そうする必要ある?

書き捨てのプログラムだったり、個人利用する程度なら別にそんな事する必要はない。
ただ、運用中のシステムで利用したり、ある程度の人数以上で利用するなら絶対といって良いほど必要である。

確かに、引数が前提を満たしていることが「理論上確実である」としよう。
でもそんな事をすれば、突然プログラムが停止することがある。

例えばこんな例だ。
関数Aの戻り値として成功すればオブジェクト、失敗すればnullを返すようなプログラムの場合を考えてみよう。

その関数Aには、潜在的にNullを返してくる可能性がある。(理論上失敗しなくても)
そこで 、動作環境の不具合で偶然Nullを返してきたとしよう。

戻り値でnull判定を行っていなければ、nullに対して色々処理しようとしてエラー吐いて処理が停止するだろう
(通称:ぬるぽ)

このような形で、忘れた頃に障害を発生させたく無ければ、引数や戻り値が前提条件に合致しているか確認するべきだ。

動作を担保する(防御的プログラミング)

これは、以下の思想に基づくプログラミング/設計手法だ。
・関数が受け取った値が確実に前提を満たし、戻り値も確実に前提を満たしている事を確認する。
また、より徹底したい場合は、以下の様なコード体系となる事がある。
・関数には確実に期待する前提を満たす引数を渡し、戻り値も必ず期待する前提を満たしている事を確認する。

これが徹底して行われている場合、全ソースの6~8割位がエラーチェック系のコードになることが多い。
エラーによる停止が許されないシステムや、管理外のシステムとの連携処理ではこういった形態をとる事が多い。

全体的に行おうとすると、単体テストでエライ目に遭うので、適切に採用しよう。
※もちろんエラー停止が許されない場合は、単体テストの工数をケチってはならない。

動作を担保する(契約による設計と実装)

これは、以下の思想に基づくプログラミング/設計手法だ。
・関数が受け取った値が前提を満たせば、前提を満たした戻り値を返すぞ。
という考え方のことである。

ここでの前提とかは、ケースバイケースなのであくまでも一例だが、例えばエラーとなった場合には
・想定したエラーならそれは契約によるので、取り決め通り処理を継続する。
・呼び出し元、関数自体の両方とも責任が無い、想定外のエラーならば、どうしようもないので例外をぶん投げる。
(要するにニンゲンでいうところの、「無理じゃねこれ?」->「分からんからあとはよろしく!」って感じだ。)

結局どうゆうことなのか?

職業プログラマならば、可能性は潰して置くべきである。

もちろん、それを納得出来るまで行っておくと以下の様な事が発生する。
「想定してたけど結局そんなこと無かったね…」
こう思う日がきっとくる。

しかしそう思う迄、意識して実装しなければ。
障害発生時、仕様変更時、単純に聞かれたときに答えに詰まってしまう。
プロならば、「なぜそうなっているのか」を説明する義務があるので、横着はしない方がいい。
(障害報告書とか出来れば一生書きたくないしね。。。)

余談

「これって別に考慮しなくてもいいんじゃね?」みたいな仕様になるときがある。
要件定義や設計段階では、別に考慮する必要もないので、考慮しない事がある。
(お節介やってバグ出すのも怖いので。)
しかしだ、こういう時に限って中々エグい追加要望が来るので、やっぱり考慮した方がいい。

最後に

結局のところ、何が言いたいかというとだ。
「誰が何をどう変更するか分からない以上は、考えられるリスクは潰しておけ」
ということだ。

おまけ

土曜日の昼食に食べる焼きそばだったり、炒飯はなぜあんなにも美味しいのか。

おわり