抽象化と再利用
- 「富士通の地銀システム開発に遅れ、新聞では分からない深層」http://biz-inno.nikkeibp.co.jp/conduct/article20030624.shtml
こちらでは「汎用的なシステムを開発しようとした」と一言で書かれているが,実はこれが極めて難しい.PROBANKにおいてどうだったかは知らないが,オブジェクト指向は拡張性/再利用性を高めることが可能な技術ではあるし,こういう場合には使うことを検討すべき技術の一つだ.しかし決して簡単なものではないし,誰にでも実現できるというわけでもない.(似非)オブジェクト指向の入門書には「その鍵は抽象化にある.」「抽象化することで再利用性に優れた汎用のプログラムになる.」のように記述されてたりする.しかしこの「抽象化」というのは得てして極めて胡散臭い単語なのである*1.
銀行システムで汎用にするのが難しいのは,おそらくは各行ごとに異なる微妙な事務手続きの差を吸収することだろう.
東邦銀行の事務規定のうち、「他行も標準的に使えるもの」、「他行とはかなり違うもの」をまずより分ける。標準的な規定についてはそのままソフトを開発し、標準的ではない場合は複数他行の事務規定を参照し、別途ソフトを作る必要がある。
の部分からもそのことが伺える*2.たとえばこれを
// 注:いうまでもなく,これは悪い例である.絶対に真似しないように!! /** * 各行ごとに異なる事務手続きを抽象化した汎用事務手続きメソッド. * 各サブクラスで拡張することで汎用性を実現する. * @param args 事務手続きに与える引数. * @return 事務手続きに対する戻り値. */ abstract public Object abstractJimMethod(Object args);
と書けば,(つまり抽象化すれば,)確かに実現することは理論的には可能だ.だがこうすることで,一体何が改善されたであろうか?何も改善されてなどいない.それどころかむしろ悪化している.そのことはメソッドの実装を見れば一目瞭然だ.分からないならば実際に実装してみればいい*3.通常は個別に実装するのとコード量も同等以上になるし,複雑さやデバッグに関する手間となると開発者の悪夢だ.RTTI*4をチェックするコードで肥大化して手が付けられなくなるかもしれない.
熟練した開発者*5ならば「こんな設計などするはずがない」「そんな設計をする人がいるなど信じられない」と言うかもしれない.それには全く同感だ*6.しかし実際にこれに近いやり方を推奨し,これこそが本当のオブジェクト指向だと信じている人もいるようなのである.
上のような設計を「抽象化」と呼ぶのは誤りだと思う.むしろ「曖昧化」或いは「責任転嫁」*7と呼ぶべきだ.このような曖昧化と責任転嫁で「汎用ソフトウエア」を実現しようとしたが最後,そのプロジェクトはデスマーチになることうけあいだろう.
オブジェクト指向の本質は,モデリングでもなければ抽象化でもない.それは実装の細部にある.このことはオブジェクト指向を学ぶ上で絶対に忘れてはならない.
*1:「オブジェクト指向では抽象/abstractionが必要ない」ということではない.良いコードには適切な抽象が暗黙の内に利用されているものだ.抽象は再利用の道具であって目的ではない.再利用性が向上するなどのメリットがあれば利用すればいいが,そうでないなら利用すべきでない.
*2:ちなみにJavaなどのオブジェクト指向言語を使って実現する場合では,上のような切り分け方はおそらく正しくない.このような標準/非標準という単純な区分だと,よほど運が良くない限りはほとんどの業務が「非標準」になる恐れがある.人間的には「ごく僅かな違い」でも機械からすると同じでないものはすべて「異なるもの」でしかない.もしこれがJavaを使っていたのであれば,基本的な設計ミスを疑う必要がある.
*3:やってみれば分かるが,そもそも実装が不可能な場合が少なくない.実装に必要となる仕様の細部が定義されていないためである.メソッドや仕様を設計する時は,前もって実装レベルの細部まで検討し,詳細に定義し文書化しておく必要がある.
*4:Run Time Type Info,実行時型情報.オブジェクト指向を使いこなした良質なコードでは明示的にRTTIを使う必要はほとんどない.RTTIを明示的にチェックするコードが異常に多い時は設計ミスを疑うべきである.このような設計のコードとしては,XMLのDOMが有名.
*5:あえて設計者とかプログラマーと書かずに開発者と書いておく.真の開発者ならば設計とコーディングを分ける意味がない.
*6:UMLモデラーならやるかもしれない.モデラーは開発者じゃないからね.
*7:本来なら抽象スーパークラスで検討しておくべき実装についての責任を一切果たさずに,その責任をサブクラスの実装者になすりつけている.正に責任転嫁.なすりつけただけで実際に実現できればいいのだが,ここまで悲惨な設計だと実装段階で破綻するのは確実だろう.鉄道事故で言えば「時速120kmに高速化する」と言うだけなら簡単だ.事実,新幹線ならそれの倍以上の速度でも安全に走行している.しかし新幹線では高速化のために車体はもちろん,レールの幅,曲率まで全て在来線とは異なる基準で作られ,踏切も無くしてある.こういう対策を一切行わずに「速度は120kmとする」とルールだけ変更しても,実装を変更しない限りは実際に120kmで安全に走行できるようになるわけではない.