しかし、その改造が何度も繰り返されたり、繰り返されずとも長期間を経て改造されたり、もしくは、大規模な改造が行われたりすると、いろいろな問題がでてきます。
3-1. 設計と実装の乖離
最初に発生しやすいのが、設計と実装の乖離です。
ソフトウェア開発では一般的に、最初に設計書を作成し、その設計書をもとにプログラムを実装していきます。
しかし、改造や修正が発生すると、プログラムの変更に設計書の変更が追いつかなくなる時があります。
この要因としては、障害発生時などはプログラムの修正が優先されることが多く、かつ最終成果物はプログラムのため、ドキュメントへの反映を忘れてしまっていること。
それ以外には、そもそも設計書更新分を見積もりに含んでいない、または、設計書更新作業が改造の見積価格内に収まらない、もしくは、お客様から設計書は不要と言われたなどがありえます。
 |
| 図1. 設計と実装の乖離 |
設計書には、設計思想や実装制限などいろいろな情報が含まれています。しかし、プログラムの改造だけが繰り返されると、その設計情報が更新されなくなり、最終的にはソースを見なければ、何も分からないという状態に陥ります。
ところが、設計思想や実装制限などはプログラムだけからすべて読み取るのは不可能に近いため、そこで重要な設計情報が喪失されることになります。
この状態になると、結局ソースを見なければ何も分からないので、次の改造における見積もりを誤り、その変更による影響範囲の見極めを誤り、最終的にプログラムの品質低下だけでなく、コスト、納期すべてに悪影響を与えます。これが、設計と実装の乖離による問題です。
ところで、いうまでもなく、設計書が完全にプログラムと一致しているということはありません。設計書は、自然言語で記述されるのに対して、プログラムはプログラミング言語で記述されます。そのため、設計書には曖昧さが含まれていたり、人によって解釈が違うため完全なものではないかもしれません。しかし、仮に完全な設計書を書いたとしたら、それは、実はプログラムが出来上がってしまうというのは、容易に想像がつくでしょう。
よって、いろいろなモデリング手法や設計手法を駆使し、必要十分な設計書にまとめ上げ、継続して更新していくプロセスが重要になってきます。尚、当社ではISO9001の取り組みなどによって、このプロセスの改善に向けて取り組んでいる最中です。
3-2. スパゲッティ化
次に、発生しやすいのがソースコードのスパゲッティ化です。
 |
| 図2. スパゲッティ化 |
プログラムは通常階層的に作成されるのが理想です。なぜなら、規模が大きくになるにつれ、対象を階層的なピラミッド構造にして分割しなければ、論理的な思考や組み合わせが人間には難しいからです。
しかし、本来は、プログラムは階層的な構造であるべきですが、いろいろな要因により階層的に作られていないことがあります。例えば、設計をきちんとしていなかった、したつもりだったが不十分だった、もっと悪いのは設計をせずいきなりコーディングし始めたなど。別の要因としては、ハードウェアの制限によって階層的な作りでは処理速度やメモリに問題がある、プロトタイププログラムだったためとりあえず動けばよいプログラムだった、小さなシステムのため階層化するコストメリットがなかった、または、短納期で階層設計をする時間がなかった、など、いろいろな要因があります。
それでも、ほとんどの小規模なシステムでは完成させることができるでしょう。
しかし、階層化されていないソフトウェアの問題がでてくるのは、次の改造からです。
統一された設計構造ではないソフトウェアは、次に改造するときも(悪い意味で)自由に改造が可能です。それはそれで、構造をすべて完全に把握している人が担当する場合には、階層化という制限がない分、容易に対応できる人もいるかもしれません。
しかし、通常は同じ人でも時間が経てば忘れるでしょうし、何より次も同じ人が作るとは限りません。
そして、構造を把握できる人がいなくなり、改造がままならない状態になった時に、プログラムはスパゲッティ化したと言われます。
それでも、一から作り直すリスクを取って改造をすることは、ほとんどありません。なぜなら、改造をしたらどこに問題が発生するかなど、この状態になったら誰にも分からないからです。そして、改造できない理由が誰にもきちんと説明できないからです。
それでも担当者は必死にコストを犠牲に頑張って改造を続けますが、いつの日か誰がどう頑張ってもコスト、品質、納期すべてを満たせなくなる時が来ます。これがスパゲッティ化による問題です。
3-3. 設計構造の限界
そして、設計と実装の乖離とスパゲッティ化をなんとか回避したとしても発生しうるのが、設計構造の限界です。
例えば、既存システムに小規模な改造が発生したとします。その時、既存プログラムの構造がもう少し違っていたらもっと簡単に対応できる、または将来的には今構造を変えておいたほうがよいだろうというケースがよくあります。
しかし、その構造を変えてしまうと今回の改造には関係ない個所での変更が必要となってしまう、または、その変更をすると影響範囲が広くなってしまうということから、今の構造を変えずに局所的な対応で実装するということがよくあります。
これは、品質、コスト、納期で考えれば、間違っているわけではありません。
それに、今回の改造には関係がなく、将来あるかないか分からない対応のために、費用や納期が掛かることを理解してくれる人は誰もいません(私がプロジェクトマネージャーの立場でもそれ相当の理由がないと認めません)。
|

|
|
図3. 設計構造の限界
|
最初の改造のうちはほとんど問題がないのですが、改造を繰り返す度に、どんどんソースが肥大化してしまいます。具体的には、関数やクラスやファイルなどです。
最初は適切な単位で分割されていたプログラムが、影響範囲を減らすための局所的な対応によって、扱える許容量を超えてしまい、結果的にその対応が、今後の変更の影響範囲を広げてしまうということが発生します。
これは機能の追加や変更だけではありません。昔は使っていた機能だが今は使わなくなってしまった機能などもあると思います。それらを削除するにも、削除による影響範囲の見極めが必要ということから、そのまま残してあるケースがほとんどだと思います。これも肥大化の要因の一つです。
更には、開発する製品によっては、機種によって機能を変えるものが存在します。それらは通常プログラムのコンパイルスイッチ
(※1)で切り替えることが多いですが、これも、肥大化の要因の一つです。
そして、この肥大化はさらに設計と実装の乖離と、スパゲッティ化の要因ともなり、更に状況を悪化させることにもつながります。
そして、ある時、当初の設計構造を大幅に変えなければ、要求を実現できない改造が発生します。途中で少しずつ構造を変えていっていれば、大幅な構造変更にはならなかった可能性はあるかもしれませんが、そんなことは誰にも分かりません。
そして、最終的にそこまで大幅な改造をしなければならないのだったら、新規に作り直したほうがよいだろうという結論にいたります。これが、設計構造の限界の問題です。