コードを短くすると単体テストが楽になる、の証明

感覚的には、コードを短くすると、単体テストが楽になり、結果的に品質があがり、最終的にはプロジェクトの成功率が上がる、ことは理解っているのだけど、人に説明すると、どうも「納得いか~ん」方が居られるので、ちょっと論理的に証明などしてみます。

# 実は、証明するよりも、「人は理解したいものを、理解する」という訳で、ロジックで説明しても無駄なことが多いんですけどね。ま、自分を納得させるためにも必要ということで。

■現状分析

ソフトウェア開発において、ステップ数でプロジェクト規模換算をしようとすると、請負側からすれば規模を大きく見せる≒プロジェクトを擬似的に大きく見せる、ためにステップ数を「実効数」よりも増やすという現象があります。
また、プロジェクトが終わった段階で、ステップ数が多いということが、イコール「たくさん仕事をした」ということで、報酬が多くなるという現象もあるわけです。

なので、ステップ数を減らすと、「仕事量が少ない」ゆえに「報酬が少なくなる」ということに成りかねないので、この話は、

・自社で、パッケージアプリケーションを開発する。
・プロジェクトの成否が、自社の報酬に影響する。

時に使ってください。

# F# などの関数言語を使ってみると、短く書く≒簡素に書くことの重要性がわかるのですが、全てのプログラマが関数言語を使ってみるというのも難しい話なので。

■背理法で証明する

厳密に言えば、最初は詭弁的な方法で論証してみます(笑)。手っ取り早いので。

1.ステップ数が多いコードがある。
2.ステップ単位で予想されるバグ件数は決まっている(品質上)
3.ゆえに、バグ件数は、ステップ数の比例する。

バグ件数 = ステップ数 × 予想バグ比率

ということで、ステップ数を増えれば、バグ件数が増える。
なので、バグ件数を減らすためには、ステップ数を減らせばよい。

証明おわり。

…っての考えたのですが、論理的に間違っているので「証明」にはなりません。「説得」にはなるけど。

weak point は、
・予想バグ比率は、一定とは限らない。
 → 例えば、自動生成されるコードは、バグを一切含まない。
・予想バグ比率は、実際は人依存である。
 → 例えば、ベテランと新人では、予想バグ比率が異なる。
・バグ件数が、そのままプロジェクトの負荷になるわけではない。
 → 例えば、細かいバグと重大バグでは、1件の重みが異なる。
 → システム試験などで見つかる(あるいは見つからない)潜在バグのほうが、プロジェクトの負荷となる。
のように続々とでてきます。

まぁ、これらの反論が、コード数を減らそうとはしない、という人の動きになるのですが。

経済心理学的に、ステップ数を減らすと短期的にコストが減る、という幻想を生み出しておくのと、現実にプロジェクトのコストが減る、という現実を作らないと駄目なのです。

■in/out を明確にして DFD 風に証明する。

ソフトウェア開発のプロジェクトの肝は、情報量を如何にして制御するか、です。
「情報量」ってのは、

・要件定義の工程で確定した契約 だったり
・アプリケーションの機能数 だったり
・Web アプリケーションのページ数 だったり

するわけですが、まぁ、一般的に「作る量」ってやつです。

# 「情報量」については、後に正確に定義しないと駄目だなぁと思っています。
# DFD を使うか、IDEF0 を使うか、そのあたりを制御しないと PERT 図に落とせないので。

ソフトウェア開発での作業量というのは、以下の法則があります。

・人が作成する量があれば、単純に時間がかかる。
 → 単純に人件費が、という話です。
 → なので自動化されるもの(自動化されたドキュメント、自動生成されたコード)は、作業量に含みません。
・人が作成するものが複雑であれば、単純に時間がかかる。
 → 同様に、頭を使う時間が必要ということです。
 → 複雑怪奇なコードでも、自動生成されたり、ライブラリでモジュール化されているものは、人に対しては「複雑」とは言いませんね。
・人とのコミュニケーションが発生すれば、時間がかかる。
 → 顧客との問い合わせ、遠隔地での電話会議、ひとりではなく複数名で作る場合などです。
 → いわゆるコミュニケーション・コストです。

さて、これを前提にすると、

コードの量が少ない場合、その状態として次が考えられます。

・コードをタイピングする時間が少ない
 → IDE などでインテリセンスを利用するとタイピングが減りますが、先の条件で「自動化」の部分にあてはまります。
 → コピー&ペーストも、タイピングを少なくする手段のひとつです。
・コードを簡素にする
 → 複雑なものよりも、簡単なもののほうが、時間が少なく書ける。
・ひとつのコードを、ひとりが扱う
 → ひとつのコードを複数名でやり取りするよりも、ひとりで完成させたほうがコミュニケーションコストは下がります。

これを因果関係で直すと、

1.コードのタイピングを減らす → 作業量が減る。
2.コードを簡素にする → 作業量が減る。
3.コードをひとりが扱う → 作業量が減る。

のいずれかのパターンになります。
つまりは、いずれかのパターンを取ると「作業量が減る」という結果が得られます。

# ちなみ言うと、「コードのタイピングを増やす」→「作業量が減る」という論理も正しいのです。
# こちらのほうは証明しません。命題は「確実に作業量が減る方法は?」なので。

この中で、1.のコードのタイピングを減らす方法で作業量を考えると、

1.コードのタイピングを減らす → 作業量が減る。
2.作業量が減る → コード量が減る。
3.コード量が減る → バグ混入率が同じであれば、バグの発生数が減る。
4.バグの発生数が減る → バグの難易度が同じであれば、不具合を直す総時間は減る。
5.不具合を直す時間が減る → アプリケーションの完成が早くなる

ゆえに、ひとつのアプリケーションを扱ったときは、コードのタイピングを減らせば、バグの発生数が減り、アプリケーションが早く完成するということになります。

ただし、これには仮説が入っています。

・バグの混入率が同じであること。
・バグの難易度が同じであること。

ですね。これはどうなのでしょうか?

例えば、perl のようなワンライナーの場合は、バグの混入率は違いますよね。また、難易度も違います。
このバグの混入率、難易度を「同じ」にする前提としては、

・コードが短くなっても、1行のコードの複雑度は同じ。

というケースが考えられます。
具体的に言えば、

・1行で扱う変数の数は、変わらない。
・1行で扱うメソッドの数は、変わらない(メソッドチェーンは、理解度を上げるが、複雑度を上げる)。

という指標があります。

なので、結論で言えば、

1行で扱う変数やメソッド数を変えずに、複雑度が上がらない状態で、
コード数を減らすと、アプリケーションが早く完成する。

ゆえに、プロジェクトの成功率が上がる。

という論法です。

さて、実務はどうなるかというのは後ほど。

カテゴリー: 開発, 設計 パーマリンク