みねこあ

mineko. A! ―from mi-neko online.

2008-08-03

[]オブジェクト指向でなぜ作るのか を買ってみました 05:23 オブジェクト指向でなぜ作るのか を買ってみましたを含むブックマーク

オブジェクト指向をわかりたいなら今すぐ『オブジェクト指向でなぜつくるのか』を読め -思っているよりもずっとずっと人生は短い。 VS お勧め本? - カレーなる辛口Javaな転職日記 について、404 Not Found さんよりお呼びが掛かりました。

普段、さんざ召還魔法を使いまくっている私としては、ここは恩返しのしどころです。けれど、敵はあまりに強大で...。




結論から先に言えば、OO の入門書としては、本書はダメです。ただ、なぜダメなのかを説明するのが難しくって。たとえば、はてブのyuguiさんのコメントみたいに

引用元の「憂鬱本みたいな感想」を読んだらこの本の悪い点は分かった。だが、学習ルートとしてはどうするのが良いんだろう。「良書」で初心者に分かるのはあるだろうか。

はてなブックマーク - お勧め本? - カレーなる辛口Javaな転職日記

(強調はあたし)


「みえる」「そこっ!」みたいな感じで問題点がわかってしまうと言う、端から見るとまるでニュータイプ(^^; な人向けに書くのは出来そうなのだけれど、ただ、それを解らない人(つまり、OOの入門書を必要とする人)に納得頂けるように 「○○だからこの本は良くないよ」と説明するのは非常に難しいです。

たとえ話で恐縮なのですが、間違っているとは言えないけれどゆがんでいるものを積み立てて行ったら、明後日の方向に積み上がってしまった・・といった感じですので、部分部分を抜き出しても駄目なところがわかりにくいし(むしろ正しいことが書いてあるように見える)、かといって筋道をたてて指摘をしだすと、OOPの本が一冊書けてしまうような感じなのです。むー、困った。


アプローチ1

取りあえず、本書にしてはめずらしく大きく外している(部分で抜き出しても有害さを説明しやすい)、 クラスの説明の部分を抜き出してみます。

この間違ったクラス説明をするために、OOPL以前の言語についての説明もワザとおかしくなっています。クラスの説明が間違っているから、「パッケージ」が OOP だとかよく解らないことが書いてあります。

「進化したOOPの仕組み1―パッケージ」は、わかりやすくオレオレでしょ?

先ほどは「まとめる」仕組みとしてクラスを紹介しました。このパッケージは、そのクラスはさらに「まとめる」仕組みです。


* * *


この本における、クラスに説明は以下のようになっています。

クラスは「まとめて、隠して、たくさん作る」仕組み

1) サブルーチンと変数を「まとめる」

2) クラスの内部だけで使う変数やサブルーチンを「隠す」

3) 1つのクラスからインスタンスをたくさん「作る」

一見よさげに見えますが、ここが歪みの震源地。かなりまずい説明です。この歪んだ土台に論理を構築すると、どうなってしまうのかを見てみましょう。

「まとめる」の部分は具体的には以下の様に記述してあります。

クラスは、変数とサブルーチンをまとめたものです。

ここでいう変数とはC言語やCOBOLなどにおけるグローバル変数のことです。

グローバル変数とサブルーチンをまとめる?この説明を「OOPならでは」にするため、3章「OOPを理解する近道はプログラミング言語の歴史にあり」で過去のプログラミング言語について説明する際、ちょっとした「嘘」が入ってます。

構造化プログラミングでは解決できない2つの問題が残りました。それはグローバル変数問題と貧弱な再利用です。

モジュールを黙殺しちゃってるんです。*1

たとえばC でも 翻訳単位をモジュールと見立てて、関数(サブルーチン)と変数を まとめたり、変数や関数の名前のスコープを限定したりすることは当たり前に出来て、「まとめて、かくす」は 普通にやっています。

そこら辺に感じやすい人(Cを使いこなしている人)が、本書の OOP を OOP だと信じると、上記で引用したクラスの定義の内、1) と 2) は OOP とは関係成しに出来る部分であることに気がつきます。そうすると今まで無かった部分と OOP ならではの部分に線引きして、「そうか!OOPってこういうコトなんだ」と、新たな OOP を発見しちゃう訳です。

たとえばコチラ。疑りぶかいあなたのためのオブジェクト指向再入門

世間の入門書では、オブジェクト指向といえば「カプセル化」「継承」「ポリモルフィズム」ということになっていると思いますが、実のところカプセル化なんてオブジェクト指向とは無関係に昔から行われてきたことですし、継承やポリモルフィズムは、 必ずしも最初に覚えなければならないことではありません。(中略)

私は、オブジェクト指向の「本質」と呼ぶべきものは、カプセル化でも継承でもポリモルフィズムでもなく、「マルチプルインスタンス」にあると思っています

疑りぶかいあなたのためのオブジェクト指向再入門

自然な帰結ではありますが、でも、これって既に OOP でもなんでもないですよね?

前橋さんが なぜオブ本を見て上記記事を書いた訳じゃないのですが、多分 なぜオブ本を読んで飲み込んじゃった人は、前橋さんの記事に納得しちゃうんです。

一見正しそうにみえていながらゆがんでいる説明を土台に、そこから思考を進めるとカオティクに歪みが拡大していくという、だから「読むべきじゃない」本かな〜、と。


* * *


余談ですが、OOPにおけるクラスは、

  • オブジェクトの処理の移譲先 & オブジェクトのファクトリ

と捉えるべきだと思います。そういうことが出来る道具か否かは別として、少なくともOOPの理解において、クラスを「変数とサブルーチンをまとめたもの」と捉えるのは あまり美味しくありません*2。あー、でもクラスそのものの構造のメタファとしては捨てがたいのはわかるのです(が私は害のほうが大きいとおもうけれど、微妙)。どうしたもんかしら。


アプローチ2

この本のゆがんだところは なにも独創的なものではなくって*3、よく目にする説明です。先ほど引用させていただいた 前橋さんのドキュメントと、本書は、とてもよく似た香りがしますが、それはこの手の間違いがとても巷にあふれているためで、それ以上の関連はないです(多分)

この手の本の問題点として本質的なところは、OOPL の機能とか、OO関連技術とかは説明するのですが、肝心の、OOP によって作られたプログラムがどの様な姿をしているかを、イメージがつきやすい形で書いてくれていないことだと私は思います。

「どんな感じになるの?」というイメージもつかめずに、ただひたすら構成要素を積み上げていけば自動的に目的地に到達できる・・なぁんてことは出来るはずもなく、道からそれても気がつかずに明後日の旅路へついてしまいます。



さて、案の定というべきか、本書で枕として紹介されている「構造化プログラミング」についても同じように間違えています。こちらの方がOOPよりも小さいボリュームで説明できそうなので、これをモデルケースに この本のおかしさの説明を試みます。


* * *


基本的な考え方は「正しく動作するプログラムを作成するためには、わかりやすい構造にすることが重要である」というものです。

具体的な方法として、プログラムを解りづらくしている元凶であるGOTO文を廃止して、ロジックを順次進行、条件分岐、繰り返しの3つの構造だけで表現することを提唱しました。

前半はよさそうですが、後半は・・・ちっがーう! GOTO文があるからプログラムが解りにくいんじゃないです。だからGOTO文を排除しただけで(3大制御構造のみで記述しただけで)プログラムがわかりやすくなるんじゃないです。

GOTO文を廃止し、三大制御構造だけで制御フローを記述するのはなぜかというと、それはアルゴリズムを切り出して部品化を行う為です。GOTO文は飛び元と飛び先を含む部分を丸ごと一塊として扱う以外に手はありませんが、連接(concatenation)、選択(selection)、繰り返し(repetition) は、入り口が一つに出口が一つの構造なので、切り出しが容易です。


ダイクストラさん曰く、「良いプログラムとは正しく動くだけでなく、 正しく動いていることが容易に解るプログラム。」であるわけで、一方でテストで正しさを証明するのは原理的に難しいため、コードの可読性を上げて「正しく動いていることが容易にわかる」ようにしようというのが、構造化プログラミングの動機になります。

そんなわけですので、理想はコードをパパっとみればササッと正しく動くこと(あるいはバグがあること)が解るようなプログラムですが、しかしそれを実現するためにネックがあります。それは人間の能力不足です。具体的には規模への脆弱性で、人はただ数が多いだけで何がなんだかよくわからなくなってしまうのです。 だからプログラムの「難しさ」が同じ程度でも「規模」が大きくなるだけで、 とたんに人間の管理能力の限界を超えてしまい、プログラムを読んでも 「正しく動くこと」を理解できなく成ってしまいます。

そんなヘタレ人類に残された最後の(?)武器が抽象化です。抽象化することで見かけの規模を減らすことが出来るため、この技を使えば 人間の理解の脆弱性を補うことが出来ます。(なのでプログラミングに限らず、日常生活でも我々は抽象化をつかいます)

構造化プログラミングはソフトウェアの抽象化技法です。プログラムに段階的詳細化する構造を持たせ、ある階層からみればその下の詳細は抽象化されるため、規模の問題を回避できるのです。

構造化プログラミングを使って作成された プログラムは、丁度技術書のような章や項で構造化されたドキュメントとよく似た姿に描かれます。この構造の箱として「関数」がつかわれ、そしてそれらの箱の中を十分に小さい規模に保つことで、人間が簡単にプログラムの正しさを読み取ることができるようになるわけです。(関数の中身は小さくしろ、というのはこういう訳)

だから、十分に小さい箱の中であれば、別に goto文を使おうが、構造化プログラミング的には無問題です(だからC のは 箱の中にしか飛べない制約が掛かった goto文でしょ?)。途中リターンも同様です。


* * *


可読性を上げることでプログラムの品質を上げるというアプローチは、ソフトウェア工学の基本であり、OOP もこの基礎の上に立脚しています。そして、OOPも 構造化プログラミングと同じ ソフトウェアの抽象化技法です。

じゃあ、OOPと構造化プログラミングって何が違うの?、ですが、乱暴に言って以下の二つになります。

  • 構造化につかう箱が違う(関数→オブジェクト)
  • 部品のつなぎ方が段階的詳細化じゃない

OOP に使う「箱」は、Simula が(OOPとは無関係に)発明した 「オブジェクト」(と「クラス」)です。これらの箱を用いて 責務分散協調系 としてプログラムを描くのがオブジェクト指向プログラミングです。

オブジェクトは小さな完結したコンピュータ。一つ一つのオブジェクトは 小さな責務をもっていて、プログラムが何か機能を果たすときには、これらオブジェクトが自身の小さな責任を果たしつつ協調し、系全体でその責務を果たします。(これらをケイは 細胞と組織に喩えました。)


まー、よーするに、ただまとめただけじゃいかんのです。抽象化せにゃな〜。(と格好良く往ってみるテスト)


この本はダメな本なのか

とまぁ、ダメなところをあの手この手で説明しようと試みてきましたが、この本が本当にダメな本かというと微妙です。この本がターゲットに挙げているひとかた

ソフトウェア開発現場に直接関わっていないIT業界の管理職の方

のように、自分が技術者でないという認識がちゃんとある方には、それほど毒にはならないんじゃないかな、と思ったり。ライトなOO本にしてはアンバランスに低レベルに踏み込んだ章が用意されているのは、昔 C をやっていて、今は現役を退いて管理職になったような方を想定されているように思えますし。JavaBlackさんの「この本を読んでも作り方は解らん」に誰かが「『なぜ作るのか』だからそれでいいじゃん」と突っ込んでた、そういうのでよけりゃ、血にも肉にもなりませんがどうぞ、という感じ。

但し、本書がターゲットに挙げている残りの二つ、

初心者の方やオブジェクト指向に一度はチャレンジしながら挫折してしまった方

日頃からUMLやJavaをつかってソフトウエア開発をしている方にとっては、自分が使っている技術の位置づけや目的を再確認するため

については、 私もJavaBlackさんの意見同様 OOPの理解を阻害する遅効性の毒が含まれていると思います。

本書はどう読んだって技術書じゃありません。正確に情報を伝えること・理解することは二の次で、飲み込みやすいことのほうを優先して書かれています。もちろん技術書であっても「入門書」ではこの傾向がみられますが、本書は入門書と呼ぶには 正確に伝えることに頓着しなさすぎで、結果「理解」することは叶わず、飲み込むしかないのです。(だからこそ、飲み込みやすいといえます)

これは 憂鬱本のような「(今となっては)間違い」とかじゃなくって、もう、確信犯ですから、だからダメ、と評価できない。ややこしいなぁと思います。










・・・・・って、ホントにそうかな。この本、本当はものすごくヤバい本じゃないのかな?

というのも、私もこの本読んで相当混乱させられて。ここはよし、ここもまぁいっかな?と確認しながら歩いているのに、気がつけば明後日の方向にいる。それが実に巧妙で、この本には方向感覚を狂わせる魔法か何かが掛かっているのでしょうか、と思うくらい。なんか階段を上ったつもりなのに気付いたら降りてる感じですよ。気付いたら迷ってます。この本には見た目のフレンドリーさに反した、なにか恐ろしいものの片鱗を感じるのですが、それが何だか説明できない...orz 魔書?。パウ・デイレルの書とか、その類の本?


細かい項目のそれぞれが、一見まっとうなこと書いてあるように見えて実は微妙に本質を外してる、でも間違ってるとバッサリするには躊躇する――そういうのばっかりで。確かにそこだけ抜き出しても間違いと言いきれないけど、ていうか間違いがコンテキスト依存してるから抜き出し指摘が意味をなさないあたり質が悪すぎですし、でも、そういう小さいゆがみでも、全体を組み上げるとなんか OO が別物になってるから、「いいんじゃん」と言うわけにもいかないというか。

で、比較的大きめにハズしている クラス周りにドライバをつっこんでこじ開けてみたのだけれど、それでもそれに対して何かを書けば書くほど、自分が明後日の方向に爆進しているイヤンな感触が強くなる。「そういうお前がオレオレだ」臭がでてしまう。あたしがダメか、ダメですかorz。


・・・らめぇっ、こんなの無理。何度も何度も書き直したけれど、全然上手く掛けないよー(T△T この本が良いと思えてしまう人にダメと納得できるように説明するのは、あたしには無理です。誰か書き直してー。

とりあえず、腕に覚えがある方はこの本を買って、恐ろしさの片鱗を味わうことをおすすめします。

*1:ここだけを抜き出せば、「構造化プログラミング」と限定されちゃえば間違いと言うのは無理になるんですが(^^; もともとこの章の趣旨「OOPL発生までの歴史を追ってOOPを理解する」からすれば、間違いと言ってしまって良いと思います

*2:もっと余談ですが「変数とサブルーチンをまとめたもの」は、クラスの出自である Simula的にも嘘になります。Simula 67 のクラス/オブジェクトは、Algol 60 のブロック(Cのブロックとだいたい同じ)を拡張したもので、「存在し続けるブロックの実例」がオブジェクトであり、その元となる手続きがクラスになります。(って、ダールのじっちゃが言ってた。)

*3:ということにしておこう。ホントのところ、ちょっとほかに見ないほどのオレオレ定義をギュギュっと拘束着の下に押し込んでいる風に感じてます。

きむら(K)きむら(K) 2008/08/04 09:29 玉石混合→玉石混交(ぎょくせきこんこう)

こーゆーのを「画竜点睛を欠く」(がりょうてんせいをかく)とゆいます :-)

minekoaminekoa 2008/08/04 10:39 ありがとうございます。
うわ、恥ずかし...orz

sumimsumim 2008/08/04 11:13 んー。個人的には、やっぱり、抽象データ型のOO(ストラウストラップら)とメッセージングのOO(ケイ)それぞれにてらしてみて、分けて批判を加えないと、批判対象書と同じ轍を踏んでしまうような気がします。

たとえば、クラス = 型(抽象データ型のOOの場合)or 移譲先&ファクトリ(メッセージングのOOの場合)のくだりとか、オブジェクト = 小さなコンピュータ・細胞(メッセージングのOOの場合) or ユーザー定義型に属する単なるデータ(抽象データ型のOOの場合。これについては言及無し)…とか。

minekoaminekoa 2008/08/04 12:46 >批判対象書と同じ轍を踏んでしまうような気がします

やっぱり...orz

OOキメラ論の話――抽象データ型のOO と メッセージングのOO の話は、えらいボリュームがふくらんでしまったのを手直しする際に「ま、いっか」ザックリ削ってしまったのですが、良くないですね。これじゃ都合の良いところをチャンポンです。まさしくオレオレです..orz


ただ、思わないこともないではなくて。

たぶんこの本は Java の OO さえフォローしていれば文句は言われない本だと思います。

でも肝心の Java の OO って、作られるプログラムのイメージはだいたい ケイのOO に近いのだけれど、メッセージは無くって、かつ、クラスが型であることを強く意識する・・・と言うキメラなものだと思うのですが(ここからして間違っているかも^^;)、これの姿を理解してもらうには、キメラの材料から説明するのがやっぱり近道なのかとか。(またはキメラをそのままの姿として説明する良い方策はあったりするのでしょうか)また、現在主流の「抽象データ型のOO」は、本当に主流なのか(寄生されているメッセージングのOO にかなり重要な部分を乗っ取られていないのか)とか思わないでもないので、ここら辺をどう説明したら良いのかとか。

あと、「取っつきやすく・間違いにくく」の良い手段として、良くできたメタファがあると思いますが、なんかそうなると ケイの独壇場にならないか(案外 独壇場と割り切って「メッセージ」とか叫んじゃった方が、結果として良い目がでるのでは)、とかとか。

いろいろ頭がグルグルです。

# 自分が解っていないことは説明できないと言うだけの話なだけなのかも(^^;

なんかあんまり私がダメダメなので、しまっちゃうおじさんにしまわれてしまいそうです。

sumimsumim 2008/08/04 13:35 とりあえず、ケイのメッセージングのOOとストラウストラップら(リスコフ、メイヤーなど)の抽象データ型のOOの要点について、みねこあさんなりの解釈を簡単でいいので箇条書きにでもしてもらうことはできますか? そこからすりあわせたほうがよいと思います。

takahashimtakahashim 2008/08/04 14:18 こんにちは! 詳細な言及、ありがとうございました。
うーん、minekoaさんの批判の一部は納得できるのですが、おそらくは「細部の厳密性の捨象はどこまで許せるのか」という点と、おそらくは「単独の入門書にどこまで求めるのか」という点で意見が分かれるのだと思います。私としては、技術者でも読むことを強く勧めつつ、もちろん本だけじゃなく実装にも触れたりとか仕様書読んだりとかもしながら理解を深めてほしいと思います。
時間がとれれば自分の日記で詳しく書きたいのですが、ちょっとあとになるかもしれません。

あと、この本でのOOPは抽象データ型のそれの方に大きくふっていると思います。

kmaebashikmaebashi 2008/08/05 01:50 >でも、これって既に OOP でもなんでもないですよね?

こんにちは。書いた人間なので出てきました。

ええと、少なくともJavaを含むストラウストラップ的なクラスベースのOOにおいては、インスタンスがたくさん作れることは、十分条件ではなくても必要条件ではあるのではないでしょうか。
C上がりのJavaプログラマが何もかもstaticで書いたら、先輩は「OOしてないぞ」と言うと思います。にも関わらず、当時そのあたりの説明がほとんどどこでもされていなかったというのが、私があの文章を書いた動機です。

minekoaminekoa 2008/08/05 03:00 なんかすごいことになってしまったので、まずは返答を。

>>sumimさん
せっかく箇条書きで良いからと言っていただいたのに、私のまとめ能力不足ですごい長さに...orz、近日別エントリでかならず、です。ダメダメで申し訳ないです。

minekoaminekoa 2008/08/05 03:10 >>takahasimさん
こんにちは♪はじめまして。

> おそらくは「細部の厳密性の捨象はどこまで許せるのか」という点と、
> おそらくは「単独の入門書にどこまで求めるのか」という点で意見が
> 分かれるのだと思います。

はその通りですね。

私としては、入門書(門をくぐる)というよりは、門の外から興味津々眺めるような、そんな風な感じに思えたので、入門書にするならNG かな?という感覚です。

この本は、かなりいい加減に書いてあるように見えて、突っ込もうとすると、はっと「間違いって言い切るとかえって間違えかも」と気づく変な本だと思います。それだけしっかりした本であるということなのかもしれません。

ただ、上の繰り返しになっちゃいますが、嘘じゃなく飲み込みやすい程度に本当じゃない表記は個別のをみれば殆ど突っ込む方が野暮なのに、「で、OOって何?」と言うときに、なんだかひどく外してしまっているように思える問題があると、私には感じられます(うまく説明できて無くて申し訳ないのですが)


> 抽象データ型のそれの方に大きくふっていると思います

同意です。

それを踏まえて、しかしこの点についても、ちょっと思うところがあります。ゆとりがあれば、いつか追加エントリを書きたいな、と思っています。

>時間がとれれば自分の日記で詳しく書きたい
楽しみです。お待ちしております。

minekoaminekoa 2008/08/05 03:13 >>kmaebashiさん
わー、(ぱ)さんです! コレはうれしい♪ はじめまして。

> インスタンスがたくさん作れることは、
> 十分条件ではなくても必要条件ではあるのではないでしょうか

なるほど。初めて腑に落ちた気が。インスタンスが作れない=オブジェクトが無い、ですので、それは確かにそうです。読解力なしですみません。(^^;

しかし、それはあまりに当たり前すぎないかな、と思ってしまうのですが、

> C上がりのJavaプログラマが何もかもstaticで書いたら、
> 先輩は「OOしてないぞ」と言うと思います。

が、当時 Javaの世界で蔓延していたのなら、それもまた必要ということですか....orz(でも本当ですか?にわかに信じがたいです)

話を戻して、前橋さんの話を聞いて、C++プライマ(3版)での OOPの説明を思い出しました。こちらは3点セットの変形として、OOP の基になる基礎概念を

- データ抽象化
- 継承
- 動的結合

と説明した上で、こちらもデータ抽象は前提として当たり前として場別枠扱いしてました。

ただ、プライマーの方では、継承と動的結合 にキモがある、というふうに説明していて、私はクラス指向に立脚しながらも、その2つを端折ってしまった前橋さんのは、(有益・無益・わかりやすい とは別の問題として、)OOP 以前 なのでは、とやっぱり思います。


(三点セットについて上記エントリで否定しておきながら、コメントでの二枚舌っぷりについては、なんというかゴメンナサイ)

kmaebashikmaebashi 2008/08/05 04:06 >その2つを端折ってしまった前橋さんのは、(有益・無益・わかりやすい とは別の問題として、)OOP 以前 なのでは、とやっぱり思います。

「OOP以前」であることはまったく否定しません。
ただ、「端折ってしまった」というのは私の意図には反します。私がやりたかったのは、「端折った」(==飛ばした)ではなく、「欠けた梯子をつなぐ」ことなんです。
順番として、
(1)マルチプルインスタンス
(2)継承
(3)動的結合
というのが正しいと思われるのなら、「端折った」ではなく、「そこまで行き着けなかった」であることはご理解いただけるのでは(って、いばって言うことではないですが(でも、継承を適切な実例で説明するのはえらく難しい))。

問題は、「あまりにも当たり前なインスタンスの概念を理解できない奴なんているのか?」ということなのかと思いますが、
その実例は
http://kmaebashi.com/programmer/object/shigoto.html
の「以前、新人向けのJava研修の講師をやったとき」とか「また別の新人君は」あたりで書きました。
http://kmaebashi.com/programmer/object/response3.html
の284さんも「実例」のひとつと言えるのではないでしょうか

sutasuta 2010/08/02 09:00 論が抽象的で偏見や憶測が混ざっているのでいまいち溜飲できませんでした。OOPと構造化プログラミングの違い(組織と細胞のくだり)についても、Cのような構造化プログラミングでも(概念としては)普通にやっていたことだと思うんだけど…例えば百数スレッドが協調する組込み系のマルチスレッドとか(=責務分散協調系)。まあ言語仕様としてインスタンス生成ができるOOPは進化だとは思います。抽象化(これってアリストテレスの時代からある考え方だよね)自体は別にめずらしい考え方じゃなくて、抽象化がより実装しやすくなったツールがOOPの特徴の一つだと思うとかいってみる。なぜオブとか疑オブとかはミクロ(それこそ細胞構成要素レベル)の話で、細胞が集まった組織の形の話じゃないし。えらそうですみません。って記事の日付が二年前ですね…

kfujiedakfujieda 2010/11/26 01:39 この本のOOPの説明はMayerのObject Oriented Software Constructionを下敷きにしているので、おれおれOOPではなくMayer流のOOPなんです。気に入らないとしたらMayer流のOOPが気に入らないということになります。OOPとOOA/OODを分けたのは悪くないアプローチだと思います。ところどころおかしいところもあるけど、全体としてはいい本だと思います。

minekoaminekoa 2010/11/26 02:47 >kfujieda さん
はじめまして。

>この本のOOPの説明は MayerのObject Oriented Software Constructionを下敷きにしている

このご指摘には申し訳ありませんが、納得できませんでした。

わたしは確かに動的なOOPが好んではおりますが、 メイヤー の OOP にも大好きです。わたしは、この本のOOP は メイヤー の OOP とは異なるものだと捉えています。

ご紹介の本では、モジュールは同時に型であり、型は同時にモジュールである、そういったものとしてクラスを説明しています。その上でモジュールとしての良い特性とは何か――開放閉鎖原則etc に触れ、また、型によるモジュールの正しさの照明――たとえば DbC と行った方向にも進んでいきます。

クラスが サブルーチンなどと同類の「モジュール(構造化エンティティ)」であり、それが同時に型であるというのは、メイヤーのOOPを語る上では大切なことです。ですが 「オブなぜ本」には、そのあたりを意識した記述は確か無かったと記憶しています。たしか「関数やグローバル変数をまとめるもの」として クラスを説明し、ポリモーフィズムやカプセル化などを一通り説明するにとどまっていたはずです。でも、それならば比較的近いのは メイヤーではなく ストラウストラップ(=OOPの三大要素(カプセル化、多態性、継承)的説明)のOOPじゃないかな、と思います。

本当は自分で読み返して確認してかコメントすべきですが、手抜きをしてしまいました。記憶違いだったら申し訳ございません(なにぶん2年前のエントリで、すっかり記憶がボケボケです)。

申し訳ないついでに、できましたら、オブなぜ本のどの辺が メイヤー の流儀を感じたのか――具体的にどのあたりが明らかにメイヤーっぽいと感じたかですとか、ここはメイヤーを「下敷き」に膨らませたり読みやすく砕いたり等した箇所だろ、ですとか、お教えいただければ幸いです。

kfujiedakfujieda 2010/11/26 12:25 クラスをどのようなものとして説明しているかではなく、どのようにクラスを導入しているか、つまりモジュール化の進化の一つの帰結としてクラスを導入しているところにメイヤーの本の影響を感じました。

あとは実行時にインスタンスが作り出す構造について説明しているところとか、クラス継承のモジュールとしての特性を説明しているところはメイヤーの本の影響だと思いました。クラスの型としての説明が欠落しているのはその通りです。

僕もメイヤーの本を読んだのは何年も前で、しかも手元にないので外してたらごめんなさい。

minekoaminekoa 2010/11/28 23:41 >kfujieda
ありがとうございます。なんとなく解りました。

参考までに、OOにはいろんな「流派」があるのですが、わたしの認識は

http://d.hatena.ne.jp/minekoa/20090120/1232478685

な感じです。

Smalltalkのノウハウを反映したデザインパターンも、型とモジュール分割の良い構造をつきつめたメイヤーのOOも、おなじ結論――「責務分散協調構造」にいきつくと考えています。

平澤さんはその経験から「階層構造化(=「現実世界をそのままソフトウエアに表現するオブジェクト指向技術」)」するOO は プログラムの設計としては良くないすることに言及しています。(これは正しい)

ですが、その先どうするかについては 「フォルダ」的利用法に終始しているように思えます。これはメイヤーの「モジュール」とは異質だとわたしは捉えています。すくなくとも責務分散協調構造へ繋がる記述は全くなかったと記憶しています。

それをオレオレと捉えるか、説明を簡略化するために大胆なミッシングリンクを置いた捉えるかは 微妙なのですが(わたしは前者だと感じたけれど、主観です)、少なくとも本書が本書の唄うような「プログラマでOOがよくわからない人」を読者に想定するのは NG だと思っています。

kfujiedakfujieda 2010/11/29 23:47 確かに責務と協調という考え方は大事です。ご存知かもしれませんが、ケント・ベックとウォード・カニンガムがOOPSLA'89で発表した論文に、Class Responsibility Collaborator (CRC)カードを使ってオブジェクト指向の教育をする話があります。僕はこの論文を読んで以来、クラス設計に迷ったら責務と協調を意識して考えるようにしています。

こちらでその論文が公開されています。
http://c2.com/doc/oopsla89/paper.html

ちなみにデザインパターンの元になっているのはC++のノウハウです。ECOOP'93でエリック・ガンマがデザインパターンについて初めて発表しているのですが、そのときにC++で書かれたET++の経験を抽象化したと述べています。

僕は責務と協調は、よいクラス設計をするための一つの指針でしかないと思っています。この点について触れられていればそれに越したことはありませんが、触れていないからと言ってNGというほど、この本はひどい本ではないと思っています。

気軽に読める分量で、「現実世界をそのままソフトウェアに表現するオブジェクト指向技術」は正しくないときちんと書いてある本を僕はほかに知らないので、この本が出たときには学生に勧めまくってしまいました。

minekoaminekoa 2010/11/30 02:09 すみません。コメントの意図が読み取れません。これは前のわたしのコメントが発散してしまっているせいでしょうか(^^; 混乱させて済みません。

勝手ながら、これまでの kfujiedaさんの意見を整理いたしますと、

+オブなぜ本は良い本だ
++メイヤーのオブジェクト指向入門の簡易版といえる内容で良書だ
++気軽に読める分量で「現実模写型OOPいくない」とちゃんと言ってるから良い本だ

という主張と捉えています。(よろしいでしょうか?)

で、わたしの意見としては、

+メイヤー本の流派的なモノは全く感じられない
+プログラマに奨めるなら「現実模写型OOPいくない」で終わるのではなく、「ならどうすればいいのよ」に踏み込まないと良い本とは言えないのでは?
+それ以外にもなんだか歪なモノを感じるけれど、上手く言葉にできない(これは今回の議論では捨て置いてください)

という主張です。

さすがに記憶だけで話を進めるのはムリ出てきましたので、遅ればせながら「オブなぜ本」を再読しました。

そして、あらためて、メイヤー本の影響は、やはり全く無いという印象を強くいしました。影響があるというなら、何故この本は「開放閉鎖原則」のかの字もないのでしょうか。DbCに一言も触れないのでしょうか。30冊ほど掲げている「より深く学ぶための参考書籍」というコーナーにもメイヤーの本は上がっておりません。(もっともこれは入手困難だったとかかもしれませんが /「オブジェクト指向入門」は2002年の再刷があったので微妙かも)

失礼ながら、メイヤー本との関連については、kfujiedaさんの勘違いかと思います。

「気軽に読める」にも関わらず「現実世界をそのままソフトウェアの表現するオブジェクト指向は正しく無い」と言及している点について評価する、という意見は肯定です。これはわたしも 本書の美点だと思います。

しかし、わたしの主張は **プログラマ向けならば** 、「ダメならどのようなモノが良いか」について記述すべきと思います。それは具体的には、実装継承と型継承の違い、開放閉鎖原則などなど、OOP / OOD において基礎中の基礎である 知識や原理原則です。

それらに全く触れていない時点で、残念ながら本書は雑学の域を出るモノではないとわたしは判断します。そして、もちろん そういう目的を主にに書かれた本なのでしょう。

# このエントリを書いたときの背景として、
#「オブジェクト指向がよくわからない **プログラマに** オススメ」という意見に
# NO と言いたかったといううことがあります。


* * *


わたしに解らないのは、「責務と協調は、よいクラス設計をするための一つの指針」とおっしゃる kfujieda さんが、にも関わらず この本を推す理由です。

「触れられるに越したとはないが・・・」とおっしゃいますが、このことに触れることによるトレードオフ――大変なページ数を割かれるとか、難易度を大きく底上げしてしまうとか、考えにくいです。ならばなぜ、この大切な部分の妥協を許せるのでしょうか。

わたしのレビューがdisり杉だ・・・というのは、確かにそうかも、と思わなくもないのです。「ちょっと言い過ぎじゃありませんか」的なツッコミは「やっぱり(^^;」といった感じです。

けれどこの本って、プログラムを書かない人がOO概略を掻い摘むための、実践よりも読みやすさに大きく軸足を置いて書かれた本ですよね? 身も蓋もないこと言えば、5章当たりの構成を見るに ぶっちゃけC全盛でプログラマを引退した管理職をターゲットに据えた本だと思います。

なので、どう贔屓目に見たって プログラマに奨めるようは本ではないと思うのです。kfujieda さんの発言の裏に しっかりした知識や技術があることを実感する度に、何がそこまでこの本を Push させるのか、その動機が本当にわからないので、なにかわたしの気付かない大きな魅力がこの本にあるのかな?と気になってしまいます。

わたしの見解は以上です。(ヒートアップしてしまいました。失礼があったらごめんなさい)


* * *


これは余談。デザインパターンについて。

おっしゃる通り ET++ を書いた経験をもとに書いたガンマの博士論文が元になっています。

ですがそれをもって「デザインパターンの元になっているのはC++のノウハウです」と言い切るのは些か乱暴・・というか不適切だと思います。GoFのデザインパターンは、C++上で培われたノウハウというよりも、Smalltalkコミュニティの影響が色濃く受け継いだものだと思います。

・・・と、kfujieda さんの これまでの見識の深さを見るに、絶対釈迦に説法だと思うのですが、Smalltalk好き としてこれだけは釣られずに居られませんでした....orz

kfujiedakfujieda 2010/11/30 14:09 意図がわかりにくくてすみません。僕の主張はまとめていただいた通りです。

どうも僕はこの本を好意的に解釈しすぎていたようです。メイヤー本との関連は私の勘違いでした。プログラマ向けではなくと「C全盛でプログラマを引退した管理職」向けだというのは言われてみればその通りです。

モジュールとしてのクラスに触れているのに開放閉鎖原則に言及がないとか、GoFのデザインパターンに触れているのにインターフェイスの継承と実装の継承について言及がないとか、要所を外しているのもその通りです。

「気軽に読める分量で『現実模写型OOPいくない』とちゃんと言ってる」この一点を大きく評価しすぎて目が曇ったのかもしれません。