「憂鬱なプログラマのためのオブジェクト指向開発講座」はどこがどうダメなのか

http://blog.usagee.co.jp/2010/11/27/level-up-programmer-2

(3)更に読んで欲しい5冊
C言語ポインタ完全制覇 (標準プログラマーズライブラリ) C言語ポインタ完全制覇 (標準プログラマーズライブラリ)
前回書くべき書籍なのに、すっかり忘れていました。。。 超有名本ですよね。
C言語使わない人も、是非読むべきです。
あわせて http://sakurai.sumomo.ne.jp/page/c_pointer も見るべき。
ちなみに、ポインタについての凄くわかりやすい説明を前どこかで見ましたので、うろ覚えながら書きます。
『ポインタって何?』『2chのレスと、そのレスへの安価』

ご紹介いただきありがとうございます。(_o_)

……それはさておき、「憂鬱なプログラマのためのオブジェクト指向開発講座」という本についてですが。

C++をメインに使われている方には、非常に不評のようですね。
確かにポリモーフィズムの使い所やら怪しい箇所は何点かあります。
ですが、僕がオブジェクト指向について学び始めた頃に読み、
当時凄く悩んだことに答えてくれた本でした。

シューティングゲームで、自機がミサイルを打ち、敵機に当たった際の判定について考えて下さい。
ミサイルの当たり判定をするメソッドがあるべきなのは、どのクラスでしょう?
ミサイルが敵機に当たった際には、ミサイルと敵機が消滅しますが、ミサイル・敵機を消滅させるメソッドはがあるべきなのは、どのクラスでしょう?
もちろん、プログラムを書き慣れている人なら、『何当たり前のこと言ってんだよ』って思われるかもしれません。
でも学び始めの人は(いや、ある程度慣れてきていても)クラスの責務について迷うことは多いはずです。
その考え方をゲームを題材としてわかりやすく学べた書として、お勧めしました。

結城浩さんが「例は嘘をつかない」と言っておられるとおり、何らかの実例を用いるのは、考え方の正当性を確認するには大変重要です。よって、わけのわからないたとえ話や抽象的な話ばかりではなく、実際の例を用いて説明する、というのは、本の書き方として、よい方法だと思います。
――それが正しいのであれば。
上記結城浩さんの文章からの引用:

実際に動くプログラムを作るというのは、ソースコードという具体例を使って、コンピュータという相手に自分の理解した内容を説明しているようなものだ。きちんと動作したら自分は理解しているし、きちんと動作しなかったら自分は理解していないことになる。

憂鬱本の場合、例を使って説明するのはよいのですが、それにより、そもそも考え方が間違っているということを晒してしまっている、というのが実態です。
どこがどうおかしいのか、id:JavaBlack 氏は具体的なことはいつまで経っても書いてくれないし*1いつかまとめようと思いながら月日が過ぎてしまいました。今もまた時間の余裕がないので、かつて書いたものを貼ってお茶を濁しておきます。

以前、私が自分のWebページで書いたものがこちら。
http://kmaebashi.com/programmer/object/naze.html

手元に「憂鬱なプログラマのためのオブジェクト指向開発講座」という本があるんですが、この本、例題としてインベーダーゲームを取り上げています。
この本によれば、仕様から「名詞」を抽出し、それに対する「操作」を抽出して、あるクラスAがあるクラスBに対して「操作」を行うのであれば、 AからBに「関連」を付けるのだそうです。そして、「関連」はポインタで表現します。関連先が複数の場合は、ポインタの配列を使えばよいそうです。
まあ、大筋で間違ってはいないでしょうが、例題として、インベーダーゲームで、ビーム砲※1 の発射したビームからインベーダーに関連を張ってしまっているのは明らかに変でしょう。
ビームが発射された瞬間、55匹のインベーダーに対してポインタを張るのでしょうか? もし、UFOが出現したり、別のビームがインベーダーを破壊したら ※2、そのポインタ配列をいちいちメンテナンスするのでしょうか?
まあ、この本には「一時的な関連」という説明もありますが(p.109)、 p.143には「"プログラムコード上ではミサイルクラスはそのメンバとしてインベーダークラスへのポインタを「持っている」必要はあります」"と明記してあるし… ※3

それより前に、ほぼ同内容のことをこちらにも書いています。
http://www.ogis-ri.co.jp/otc/hiroba/oosquare-ml/Archive/200204.month/2595.html

私も、評判がいいので、この本をamazonで取り寄せて読んだんですが。

読みやすいのは確かです。

でも、この本は、やっぱり「わかったような気にさせる」本でしかないと
思います。実作業への導入を考慮して「まじめに読む」には、正直、
内容がひどすぎます。

「文字列」を継承して「末尾スペース除去可能文字列」を作るなんてのは、
オブジェクト指向をかじりかけの初心者さんがやってしまいそうな「間違い」
ですし。

「ミサイルがインベーダーを持っている」なんて主張する人は、おそらく
世の中にはひとりもいないだろうし。

だいたい、ビームを発射した瞬間に、ビームが全インベーダへのポインタを
持つようなプログラムなんて普通書かないでしょう。あの本の通りに書いて
いったら、インベーダーはできないですよ。

まだまだ言いたいことは山ほどあるんですが、眠いのでこの辺で。

某プライベートなMLに書いたものがこちら。

Date: Sat, 08 Sep 2001 21:18:32 +0900
Subject: 憂鬱なプログラマのためのオブジェクト指向開発講座

「憂鬱なプログラマのためのオブジェクト指向開発講座」という本が
2chでえらく評判がよいので、amazon.co.jpで購入して今読んでいるの
ですが。

うーん...

この手の本は、「従来の技法を不当に貶めることで自分の支持する
方法論を推奨する」という傾向がよく見られるものですが、この本も、
もろにそういう本ですし。
# まっとうな設計者なら、Cだって、システム全体をモジュールに
# 分割して限られたインタフェースのみで操作するようにする、
# ぐらいのことはやります。

「文字列」を継承して、「末尾スペース除去」メソッドを持った
「末尾スペース除去可能文字列」を作るのがよい、なんて話を読んだ
あたりで、いい加減放り出したくなっています。

「クラスの関連にはis a関連とhas a関連がある」というのを「伝説」
として否定しているけれど、

例えば、インベーダーゲームで、ミサイルはインベーダーとの間で
当たり判定をします。よってこの2つのクラス間には関連があり、
プログラムコード上ではミサイルクラスはそのメンバとしてインベーダー
クラスへのポインタを「持っている」必要はあります。しかし、
分析的視点から考えると、「ミサイルがインベーダーを持っている」
ということは現実から離れすぎています。

ミサイルがインベーダーへのポインタを持っている、ということを
has aの関係だと主張している人が世の中に存在すると思うことの方が、
現実から離れすぎていると思うんだけどなあ。

# だいたい、この本のインベーダーゲームの分析では、実際のゲームは
# 作れないと思う。普通、ミサイルがインベーダーへのポインタを持つか?
はっきり言って、私には「トンデモ」にしか見えませんが...
他に読んだ方がいれば、感想をお聞きしたいです。

うーん、ここも同じようなことしか書いてないですねえ。他にもいっぱいおかしなこと書いてるんですけど。Java読書会BOFのMLにはちょっと違うことを書いたはずですが、今アーカイブが見えません。

だいたい、魔方陣のプログラムをCで書くとこうなるぞ、と言ってる時点で、この本がトンデモでしかないというのはどう考えても明らかだと思うんですが。
http://kmaebashi.com/programmer/object/list1.txt

今でこそ、憂鬱本の批判はかなり目にするようになりましたが、私がこれを購入した頃(「Java謎+落とし穴〜」の執筆途中だったはず)は、ネットには、私の見た範囲では絶賛の声しかありませんでした*2

世間の評判なんてものがいかに当てにならないかというひとつの例ではないかと。

(追記)
これだと「疑りぶかい〜」に書いてることから追加情報ほとんどないなあ。今週末にはもっと書く、と自分にプレッシャーをかけておきます。

*1:ていうか具体的な理由を挙げず批判するのは単なる中傷です。

*2:「俺は昔から指摘してたんだぜ」という自慢に見えます? まあそうかも。