続きを書きました → 伝えなければ伝わらないという当たり前の話

ソフトウェア開発に関する相談を受ける中で、どうもソフトウェアというものの特性について誤解をされているな、という思いを持つことがあります。

そうした場合、聞いてみるとプログラミングの経験が無かったり、殆どプログラミングには携わったことがないという方が多いです。

ソフトウェアを開発しようとするならば、ソフトウェアという特性をよく知った上で、プロジェクトは運営した方が良いし、うまくいくはずです。そしてソフトウェアならではの特徴を知るのに、プログラミングの経験はとても重要です。

この記事では、プログラミング経験の無い方が陥ってしまいがちな、ソフトウェア開発にまつわる誤解について考えてみました。

Harry Potter is Ready for Divination
Harry Potter is Ready for Divination / weekbeforenext

誤解:既にあるソフトウェアを流用した方が速く作れる

「御社でお持ちのパッケージを改良したら速く出来ませんか?」

こうした相談の場合、うまくいかないケースが多いです。既に販売されているような、ある程度作り込まれた機能があるソフトウェアには、思想やコンセプトがデータモデルの中に詰まっています。

一部の機能だけを流用するというならば考えられなくもないですが、コンセプトを実現したソフトウェアとデータモデルを流用して、別のコンセプトのソフトウェアを作るというのはうまくいきません。

コンセプトや思想の異なるソフトウェアを作ろうとするのであれば、やはりゼロから作り上げる方が、下手に流用して作るよりも速く、そして、メンテナンスしやすいものが出来上がります。

そのソフトウェアの中身で使うライブラリなどは流用した方が良いでしょう。車輪の再発明は避けるべきです。つまり、部品の流用と完成品の流用は違うのです。

完成品から引き算や足し算で改良していったとして、必ず使わない無駄な部分が出てきます。そうした意味のないソースコードを残すことは、メンテナンス性を下げてしまいます。

やはり、自分なりのコンセプトがあるならば、ゼロから必要最小限で作っていくこと、その中で必要な部品は使えるものは使っていく、というスタンスが良いはずです。

誤解:ソフトウェアはハードと違って後から容易に直せる

「機能改修に時間がかかりすぎるの、なんとかなりませんか?」

たとえソフトウェアであっても、どれだけ容易に直せるかは、そのソフトウェアのつくり方によります。たとえドキュメントがあっても、ソフトウェアの場合は容易に直せないケースが多くあります。

例えば、似たような機能を実現されている箇所が数カ所あったとして、そこがコピー&ペーストで作られていて、共通化されていなければ、修正箇所は一つで済まないため、メンテナンスにかかるコストは高くなってしまいます。

そして、きちんと共通化されているかどうかというのは、ドキュメントに表現しきれるものではありません。ドキュメントの中でコピー&ペーストされてしまっていたら、もはや手に負えません。

そこで、結局はソースコードを読むことになる訳です。ソースコードが直しやすいかどうかを見るにはソースコードを読むしか無く、ドキュメントさえあれば誰でも容易に直せる訳ではないのです。

ソフトウェアは、一度でも複雑になってしまったり、コピー&ペーストによって重複が産まれると、それをシンプルな状態に戻すためには、作られてから時間が経てば経つほど難しくなってしまいます。

ソフトウェアで高いメンテナンス性を実現するためには、最初からなるべく複雑にならないよう、重複のないように少しずつ維持し続けることが、結果として最も低コストな方法になります。

誤解:誰が作っても中身は同じ品質になる

「リリースしたサービスの保守から引き受けて貰えませんか?」

実は誰かの作ったプログラムのメンテナンスほど苦労するものはありません。前述の通り、最初から完全にシンプルに重複も無く作られ続けたものだとしたら、うまく引き継げるかもしれませんが、そうでなければ悲惨です。

これは、ソフトウェアの内部の品質は、人に依存する部分が大きすぎることにかかっています。完成されたソフトウェアの画面のようなユーザインタフェースからの操作で確認をして、もし同じ動作になっていたとしても、作る人やチームによって、その内部の品質は大きく違ってきます。

ソフトウェアのメンテナンス性の高さは、外から確認は出来ません。チェックリストやテストで確認できるものでもありません。ソースコードそのものを確認するようなコードレビューが必要です。

とはいえ、コードレビューによるチェックを、リリース直前の機能確認のタイミングでしたところで、もはや手遅れになります。足りない機能や出来てない機能については、追加することで対応することができるかもしれませんが、複雑になってしまって時間の経ったソフトウェアは元のシンプルな状態に戻すには相当なコストが必要になるからです。

コードレビューをするとしたら、日々の開発の中で実施していくことでメンテナンス性を維持するのがベストです。しかし、コードレビューをしたかどうかのチェックでは担保しきれないのは自明です。結局は、内部品質は、人やチームに依存するのです。

プログラムには「美しさ」があります。これはプログラミングをしたことが無ければわからない感覚かもしれません。美しいプログラムはメンテナンス性も高くなります。

誤解:共通部品から先に作ることが出来る

「まずは共通部品を作ってしまえば、後は並行に作れませんか?」

いくつかの画面や機能で共通と思われる部品を先に作った方が効率的だ。もしくは、今後に必要な機能を予め備えた基盤を作ってしまった方が効率的だ。こんな考えに囚われている人は少なくありません。

しかし、実際はそうはうまくいきません。共通部品の設計というのは非常に難しいものです。机上で設計をするにしても、その共通部品を使う側の機能の設計をしなければ、どんなシチュエーションにも対応できるような部品を設計しなければいけなくなります。しかし、それは難しい。

では共通部品を使う側の設計をするという行為は、どこまで設計をすれば良いのかといえば、内部のことになるためソースコードのレベルまで設計をしなければいけません。ソフトウェア開発において、設計とはソースコードを書くことなのですから。

ソフトウェアにおいて、共通の部品というのは、部品から作っていくのではなく、実現しようとする機能を作っていく中で、重複しそうな部分が出て来たら共通化して部品のように外部化していくのが自然です。

また、どんなシチュエーションにでも使えるような抽象度が高く、汎用的なものであれば、オープンソースで誰かが作っている可能性が高いです。そこまでのものは、自分で再発明する必要はありません。

共通部品から作って無駄なコードを増やして複雑にしていくのではなく、重複するコードから共通化して部品を外に出していくことで、シンプルな状態を保つことを考えた方が、長期的に見て、メンテナンスしやすい状態を保てます。

誤解:人を増やせば一度に沢山の機能が作れる

「この期間に間に合わせるためにはどれだけ人が必要ですか?」

人を増やせば一度に沢山の機能が作れるという誤解は、どれだけ経ってもなくなりません。ソフトウェア開発は、畑を耕すように一斉に人が動けば同時進行できるような単純な労働ではないことを認めなければいけません。

ソフトウェアを設計し、それをプログラミングで表現するという行為をしたことがなければ、このことを理解することは難しいのかもしれません。ソフトウェアの開発をビルやダムを作るのと同じだと思っているのではないでしょうか。

ソフトウェア開発において、設計書通りに構築するという工程にあたるのはコンピュータのコンパイルやビルドに相当する部分です。ソフトウェアがどのように動けば良いのかを記した設計書とはソースコードのことで、プログラミングこそが設計です。

性能の良いコンピュータを使えば、コンパイルやビルドの時間は短縮出来るかもしれませんが、ただ人を増やせば高い生産性が出せる訳ではありません。

ソフトウェア開発において、もっとも一人当たりの生産性が高くなるのは、1人で開発をしている時です。コミュニケーションはコストだからです。人数を増やしていけばコミュニケーションにかかるコストが増していきます。そして、同時にそのコミュニケーションを管理していくための人が必要になり、それもコストになります。

実際に生産的な活動が出来る人間を3人いたとして、その3人をまとめる人間が必要になり4人となって、4人の意思疎通にかかるコストは、一人当たりの生産活動を二分の一以下に阻害するイメージがあります。テーブルに2人しかいない時と、4人いるときに、一人当たりの発言時間が同じだとしたら、4人のテーブルは共有するのに時間はかかるのは自明です。

人数が増えれば増えるほど、調整にかかる時間が増えていくことで、長い期間が必要になってきます。本当はリリースまでの期間が大事ならば、人を増やしてはいけません。

誤解:正確な見積もりを出すことが出来る

「始める前にざっくりで良いんで見積もり出来ますか?」

ソフトウェアの見積もりは本当に難しい。

どんなライブラリが使えるのか、どんな問題で詰まってしまうのか、共通化していくコストはどれくらいかかるのか、人によって生産性は違うし、人の数が増えれば増えるほどコミュニケーションコストの係数も見えなくなってしまいます。

それでも見積もりをしたいというならば、やはり仕様や根拠が必要になるはずです。もしビルを建てるといったときに、設計もしないで見積もりをするというのは不可能ではないでしょうか。

ソフトウェアの場合、本当に正しい見積もりをしようとするならば、ビルの設計書にあたるものとして、どうやって作っていくかという設計書、つまりソースコードが必要となります。ソースコードを作らなければ見積もりが出来ないけれども、その時点であれば既に見積もりの意味がなくなってしまっているという齟齬がおこります。

ソフトウェアは、建築と違って模型を作ることが出来ないので、スケールを小さくして見積もることは難しいでしょう。また、同じ機能を沢山つくることはないので、ビルのフロアの数を増やしていくような、かけ算の見積もりも難しいでしょう。

果たして、ざっくりの見積もりに本当に意味はあるのでしょうか。もし、ざっくりの見積もりで予算を超過するというならば、どうするのでしょう。無い袖を振ることはできません。

だからといって、どの機能を削ればどの位のコスト削減になるのか、といった話をするためには、ざっくりの見積もりで出来るとは思えません。

意味のある見積りが出来るとしたら、実際に体制を組んで、動くソフトウェアを作るところまでを含めた開発を数ヶ月でも進めていくことができたら、それから数ヶ月先にどれくらいできるかは把握できるようになるでしょう。

まとめ

今回は長くなったので、6つの誤解をまとめてみましょう。

  • 既にあるソフトウェアを流用した方が速く作れる
  • ソフトウェアはハードと違って後から容易に直せる
  • 誰が作っても中身は同じ品質になる
  • 共通部品から先に作ることが出来る
  • 人を増やせば一度に沢山の機能が作れる
  • 正確な見積もりを出すことが出来る

たとえこれらのことを理解できたとしても、どうしようもないケースも多いでしょう。

ざっくり見積もって、既存パッケージを応用させて、共通基盤を作ってから、一気に人を投入して、なんとか作ってしまう。その結果、メンテナンスにコストがかかって、だんだんと改修できなくなってしまうものが出来上がってしまう。

そんなことを繰り返さないために、ソフトウェアの特性を理解した上で、そもそものところから見直すことにも取り組んでも良いのではないでしょうか。

続きを書きました → 伝えなければ伝わらないという当たり前の話

追記:本当に伝えたかったこと