Oh 脳《142》又々・Java の常識は OOP の非常識

記事一覧Oh 脳: after ZERO《其之佰肆拾弐》

又々・Java の常識は OOP の非常識
違いの分かるプログラマーのその先に

《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2009/12/03

セミナーの枕で紹介した小ネタ集です。息抜きや話題作りにどうぞ (^.^)

前回前々回 と、次のような話題を提供しました。


純粋な OOP の世界では、

  • (1) a < b (2) b > a

が同じ結果になる保証はありません。さらに、

  • (3) a == b (4) b == a

が同じ結果になる保証すらないのです。
これらを演算子ではなく「メッセージ」として実現するときには注意が必要です。


演算子から「メッセージ」へと発想の転換が進むにつれて、新たな問題に直面します。

  • (5) 3 + 4.0 (6) 3.0 + 4

どちらも同じ結果が得られます。ただし、演算子としては同じでも、メッセージとしては異なります。なぜなら、メッセージの解釈は、従たる存在の演算子「+」ではなく、主たる存在のオブジェクト 3(int) と 3.0(float) に委ねられるからです。数学の世界と違って、計算機の世界では、内部表現(ビットパターンは同じでもその解釈)が異なります。そのため、整数に対する加算のアルゴリズムを、そのまま浮動小数には適用できません。つまり、(5) と (6) では、メッセージ + に呼応する、メソッドの実現方法が異なってしかるべきなのです。


ベクトル課題では、次のような演算を試みました。

>>> v = Vector(3,4); v
(3, 4)
>>> v * 2
(6, 8)
>>> 2 * v
(6, 8)

演算子「+」と「*」との違いはあるものの、むしろ重要な違いは「メッセージを解釈してメソッドとして実現する」ときの問題です。新たなクラス Vector を定義するときに、演算子「*」に呼応するメソッド __mul__ を実現するのは当然です。問題は、既存のクラス(組み込み型 int)が、新規のクラス Vector にどう対処すべきかです。

伝統的な手法では、switch 文に象徴される、条件分岐を追加するという戦略を取ります。しかし、この戦略の問題点は、新たなクラスが登場するたびに、既存のクラスを再構築しなければならないことです。これは(int を含む)既存のモジュールを「永遠に閉じられない」ことを意味します。つまり、OOP を支援する開放閉鎖原則〔Open-Closed Principle; OCP〕に違反します。この原則では、拡張に際しては開いて(open)、変更に際しては閉じて(closed)いることが必須です。

switch 文や for 文に象徴されるハードコーディングの隘路は、要求仕様が変更されるたびに、既存のモジュールを再構築せざるを得ない「プログラマーの憂鬱」にあります。つまり、西暦2000年問題と同じ「メンテナンスの悪夢」という病巣を抱えてしまいます。これが「switch 文の呪縛」から逃れる術を持たない、ハイブリッド型 OOP 言語の致命的な欠陥のひとつです。


... zap ...
また、センター試験の時期が近づいてきました。
今年こそは「続々・センター試験:問題を見ずに正解が分かるとしたら」が、
「Oh: 脳」の話題にならないことを祈るばかりです。

Last updated♪2010/01/02