2013年7月1日月曜日

なぜ抽象化しなければならないのか

とにかく抽象化は大事なんだよJK

プログラマーにとって、
"抽象化技法を身につけた方が良い"というのは自明の話です。

構造化プログラミングしかり、
オブジェクト指向プログラミングしかり、
◯◯(好きな用語を入れよう)プログラミングしかりです。

あまりにも自明すぎて、
この事実の重要性を伝える段階になって困ってしまいます。

重要とだけ叫んでも理解されないのはこれまた自明なのですが、
でも実例を紹介してもやっぱり理解されない気がします。

自分の経験と照らしあわせて実例を噛み砕いて理解しようとするでしょうけど、
理解していなければ自分の経験に適用させることができません。

つまり「自分は使うことはないだろう」という結論に陥ってしまい、
それ以上の学習が止まってしまうのです。

結局、今まで抽象化技法を身につけることができた人達は、
学習の情熱が冷める前に理解できたのだと思います。


n分間待ってやる

今回のお話は、
その情熱が冷めるまでの時間を伸ばすための説明です。

少しでも良いので、
「理解できれば今までよりも少しは良くなるかもしれない」と思わせるのです。

そうして学習を続けてさえもらえれば、
より多くの人が新しい抽象化技法に目覚めてくれる…かもしれません。


抽象化すると何を"ゲットだぜ"できるか

ぶっちゃけた話をしてしまいますと、
レベルの高い抽象化技法を身につけていればこんなことができるようになります。
  • 大きなソフトウェアが開発できる
  • 中~大くらいのソフトウェアの開発速度が向上する
  • 小~大くらいのソフトウェアの保守性が向上する
大きなソフトウェアになると、
もう開発できるかできないかに関わってきます。

色んなブログで、
「優秀なプログラマー少数でやればあのプロジェクトは成功したかもしれないのに…」
的な記事が読めるとおもいます。

これは赤字とかではなくて、
何かの事情でプロジェクト自体が破綻したパターンです。

プロジェクトチームは足並みを揃えるために、
一番レベルの低い人に合わせる傾向があります。

つまり抽象化技法が最低のものしか採用できず、
チーム編成の時点で詰んでいることも珍しくないわけです。


プロジェクトの破綻とまでいかないにしても、
赤字だったプロジェクトが黒字になる可能性は大幅に上がるでしょう。

同じ期間を少数の人数で完成させてしまうことができますから。

つまり一時的とはいえ、
レベルの低いプログラマーを使うこと自体が損失と言えます。

…あ、しまった。

少人数だとしてもプロジェクトの値段が変わらないことが前提です。

これは人月計算の見積もりによる矛盾の話なのでスルーするとしましょう。


そしてソフトウェアは完成した後の方が大変です。

使っているうちにバグが見つかるかもしれませんし、
機能を追加したり差し替えたりしたくなるかもしれません。

その時に適切な抽象化を行ったソフトウェアは簡単に対処することができます。

ちょっとした修正でもえらく時間がかかるソフトウェアがあれば、
それはレベルの低い抽象化しか行なっていないわけです。


利点は認めるけど、自分のプロジェクトには関係ないから…

と説明して分かってもらえれば、
世の中のプロジェクトはもっと成功していることでしょう。

抽象化技法を理解していなければ現行との比較ができないからです。

評価できない、よく分からないものをプッシュされても詐欺師と思われるだけでしょう。

なのでもう一歩引いてみることにします。

「抽象化技法を学ばないなんてありえない!」

ではなく

「抽象化技法を学ぶ価値はあるんじゃないかなぁ?」

くらいを目標に据えて考えなおしてみましょう。

それくらいなら話を聞いてもらえるかもしれませんから。


複雑度が違うのだよ!複雑度が!

目標を決めたところで、
抽象化技法の利点についてもう少し深く掘り下げてみましょう。

そもそも抽象化技法を実施することで、
なぜ様々な利点が生じるのでしょうか。

それは抽象化技法がなぜ生まれたかを知れば簡単です。

抽象化技法は、
ソフトウェアの複雑さに対処するために生み出されたのです。

つまり抽象化技法がもたらす利点とは、
ソフトウェアの複雑さを軽減することによって生じているのです。

ちょっとイメージを表にしてみました。


横軸がソフトウェアの開発規模です。

対数表記なので、
目盛の上昇幅は1、10、100、1000、10000…みたいな増え方をしています。

といってもイメージなので、
具体的な数値は表記されていません。

縦軸はそれに対するソフトウェアの複雑度です。

こちらも対数表記です。

仮に表の上限を突き抜けたら、
保守不能レベルということにしておきましょう。

各色の線は、
採用した抽象化技法の違いを表現しています。

濃いオレンジ色の線は、
ろくに抽象化技法を使っていない状態です。

ループすら使わず、
もうただひたすらに保守不能に向けて一直線です。

構造化プログラミングを採用したあたりが、
薄いオレンジ色の方でしょうか。

ループや関数を記述しなければならない分、
ちょっぴり初期コストが掛かっています。

でもすぐに交点を迎え、
あっという間に構造化プログラミングを採用した方がよくなります。

まあどれだけ使いこなせるかでこの線は簡単に上下してしまうのですが、
それなりに使いこなせていると思ってください。

次の黄色は…オブジェクト指向プログラミングにでもしましょうか。
※実際には構造化プログラミング+オブジェクト指向プログラミングかな。

クラスを作ったりしなければならないので、
初期コストは構造化プログラミングのみより大きくなります。

でもやっぱりすぐに追いぬいて、
オブジェクト指向プログラミングを採用した方がよくなります。

次は…何だか面倒くさくなってきましたが、
緑色はデザインパターンを使いこなしているあたりにでもしましょうか。

さらにさらにぃ!
初期コストはかさみますけどやっぱりすぐに追い抜きます。

たださすがに初期コストが無視できなくなってきました。

状況を見ての取捨選択も必要になってくるあたりでしょうか。

エメラルドグリーンは…
もう何でもいいですがさらなる抽象化技法です。

初期コストはもっともっとかかるでしょうけど、
やっぱりどこかで逆転します。

ものすごーく大きなソフトウェアが開発できるようになりますが、
初期コストも大き~いので、
価値を見出す人も価値を見出す場所もごくわずかかもしれません。


複雑度の交点を探せ!

この話で重要なポイントは、
抽象化技法を選択したことによる複雑度の変化、及びその交点です。

抽象化技法は、
上位のものほど記述的な意味で初期コストが発生します。

その面倒さが報われるのは、
ある程度の大きさのソフトウェアを開発したときになります。

これが一種の初心者殺しで、
例えばオブジェクト指向プログラミングの利点を説明しようにも、
その利点が体感できる規模は参考書のサンプルにするには大きすぎてしまうのです。

そしてもう一つ、
抽象化技法を会得するまで、
複雑度の交点がどこにあるのかは分からないのです。

今までの記述よりも量が増えるにも関わらず、
サンプルで利点も分からず、
目標もよく見えない、
なのでごく短期間に理解できる人間でないと諦めてしまうことが多い。
※もしくは直感的に利点があることまでは理解できるか、かな。

それが抽象化技法の特徴なのではないでしょうか。


結局何が言いたいわけ?

会得しないと利点が分からない性質のものだから、
有名な抽象化技法くらいは頑張ってみたら?

少なくとも、
複雑度の交点が見えるようなるまでは。

え、何が言いたいか分からない?

自分も分からないんです…

0 件のコメント:

コメントを投稿