オブジェクト指向の次の思想は?
【1】オブジェクト指向という概念は、20年以上叫ばれてきた。
でも、正直、聞き飽きた所がある。
オブジェクト指向を生かした設計手法であるUMLも、以前よりもコミュニケーションが取りやすくなったが、所詮ダイアグラムに過ぎない。
オブジェクト指向開発プロセスの集大成であるRUPは、もはや馬鹿でかい開発プロセス。
誰もそれを完全にマスターすることは難しい。
プログラミング技術では、オブジェクト指向の最大の利点はポリモルフィズムだ。
一つの型(インターフェイス)を複数のインスタンスで動的に振る舞いを変える仕組み。
Javaでポリモルフィズムを実現するには、普通は継承を使う。
デザインパターンはオブジェクト志向のカタログ。
デザインパターンは、C++のベストプラクティス。
Javaもそれを引き継いでいる。
ポリモルフィズムを使いたい状況は、複雑な条件分岐。
いわゆるswich文、IF文が羅列しているプログラムを、複数のクラスへ分割する手法。
特に、業務システムは、業務の状態判定をフラグとIF文で実装していくうちに、IF文がどんどんネストして深くなって、誰も修正できなくなる。
状況に応じて、下記3つのデザインパターンを使うのが普通だろう。
それぞれの条件分岐のクラスのインスタンスは、FactoryかAbstractFactoryクラスで生成する。
1.switch文やIF文の状態判定から、状態やアルゴリズムを抽出する
→State/Strategyパターン
2.swich文で二つの型を比較して条件分岐したい時(いわゆるマトリックス型分岐)
→Visitorパターン
3.それぞれの条件分岐のアルゴリズムを組み合わせて、最大値や最小値を取り出したい時。
State/Strategyパターンの変形と言える。
→Decoratorパターン
継承構造が複雑な場合、継承構造を複数のビューから眺めて2つの継承構造へ分離するBridgeというデザインパターンもある。
でも複雑性に対応しきれなくなっている。
一度、継承構造を入れてプログラミングすると、機能追加していくうちに、継承が深くなりがち。
【2】最近、Ruby、JavaScript、Scalaのようなスクリプト言語や関数型言語に触れて、ポリモルフィズムの実現方法が変わってきている気がする。
うしおさんの記事「私がScalaを選んだ理由 [初級~中級] JavaとRubyとScalaの比較」を読んで、その理由が少し分かった気がした。
結論から言うと、RubyやJavaScriptは、Javaと書き方が違う。
それは、関数型言語の発想と言っていいと思う。
その特徴は二つあると思う。
一つは、リフレクションを多用したメタプログラミング。
そしてクロージャ。
例えば、条件分岐はリフクレクションで極限まで共通化する。
それができるのは、スクリプト言語という特徴があるから。
型にとらわれないからできる。
Railsはmethod_missingという特徴がある。
これは、メソッドが無ければ勝手に生成してくれる。
正規表現が強いRubyらしい。
Railsはリフレクション使いまくりだ。
他にも、メソッドチェーン、短絡評価など。
ループ処理はクロージャで簡略化して書ける。
Javaなら、無名関数や無名クラスを作るのが面倒だが、スクリプト言語は、関数がファーストクラスなので、関数をプロパティのように扱える。
これらの性質を使うと、継承構造を使わなくとも、フレームワークが後で動的にメソッドを追加して、機能を増やすことができる。
JavaVM上で動く関数型言語Scalaでは、Implicit conversionsという機能がある。
これは、型を拡張する方法。
Implicit conversionsはまだ理解し切れていないけど、これを使うと、型を変更すること無しで、パッチのようにメソッドを追加できる。
詳細は、keisukenのHPを見よ。
そこでは、PersonクラスにImplicit conversionsを当てると、RichPerson.ageのインターフェイスを実行できる。
Personクラスには、ageインターフェイスはないのに!
【3】今まで手続き型言語の日陰に隠れていた関数型言語がにわかに存在感を増してきた理由は、WebとマルチコアCPUの普及だと思う。
WebもマルチコアCPUも、並列処理、分散処理に特徴がある。
今まで、1個のCPU上で、マルチスレッドに気遣いながら手続き型プログラミングしてきた。
でも、マルチコアCPUでは、ロジックを複数のプロセスへ分解して、プロセスを平行に走らせるようプログラミングする。
Webプログラミングも同じ。
複数のクライアント、複数の画面から飛んでくるリクエストの状態を保持する機構は、セッションしかない。
セッションはグローバル変数と同じ。
昔のデスクトップアプリのメモリリークと同じ問題構造を持つ。
「プログラミングErlang」では、こんな一節がある。
なぜマルチコアCPUを気にするのか?
(中略)
デュアルコアマシンでプログラムが2倍以上速くなっても深い意味はない。
(中略)
2倍の高速化くらいでは驚かないにしても、10倍なら話は別だ。それが100倍なら本当にすごいことだ。
今日のプロセッサは高速で1つのコアで4つのスレッドを並列に実行できるので、32コアのCPUならば128個分のスレッドを使える可能性がある。
つまり、100倍の高速化も射程内にあるということだ。
100倍高速になるなら黙ってられない。
実現するにはコードを書けばいいだけだ。
そう、今のJavaに不満があるなら、コードを書けばいいだけだ。
| 固定リンク
「プログラミング」カテゴリの記事
- Javaのモジュールシステムの考え方をまとめてみた(2022.10.21)
- Javaのモジュールシステムは複雑性をより増している(2022.09.10)
- Javaはなぜ関数型言語になろうとしているのか(2022.09.02)
- Javaのラムダ式の考え方(2022.08.10)
- Javaはオブジェクト指向言語ではなく関数型言語だった~「[増補改訂]関数プログラミング実践入門」はお勧めの本だ(2022.08.06)
コメント