おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

デザパタを一人でこっそり振り返ろう #1 (Iterator)

2011.02.27 注記:umejava さんのコメントにより、一部間違った記述を訂正。


最初は読書会に参加して勉強させて貰うつもりだったんですが、本来の趣旨であるところの:

GoF を基礎から丁寧に振り返りましょう

というテーマを無視してヨタ話に突っ走り、それはそれで非常に面白かったんだけど、むしろ基礎を押さえたい人を置いてけぼりにしてしまったことにいたく反省をして、読書会は抜けたわけで。

でも、そのためにせっかく買った

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

がもったいないやん! ということになり、抜けた読書会と同じペースで振り返ろうかな、とか思ってたらすっかりサボってしまいました。

そしたら注文してた、

Design Patterns Smalltalk Companion, The (Software Patterns Series)

Design Patterns Smalltalk Companion, The (Software Patterns Series)

が届いたので、眺めたら面白いのなんのって。


つーことで、以下さらさらっと舐めたいと思います。
以下結城先生の本は JDP、Smalltalk のヤツは DPSC と略記します。

Iterator パターン

d:id:naruoga:20110210:1297363662 で振り返った内容なわけですが、DPSC の見解は Ruby などの動的言語でも通用するんじゃないかな。

内部イテレータ

「ある固まり (Aggregator) に対して、その要素すべてにある処理を順に実行していく」という、その「要素すべてに」順次実行していく、という制御そのものを内部に隠蔽してしまうのが内部イテレータ

  • Smalltalk の場合 Collection クラスだったら内部イテレータを容易してるから、それ使えばおけ。具体的には do: で実行ブロックを渡すというありがちなやり方。
  • 逆に言えば Collection のサブクラスは do: を適切に実装しなきゃダメ。
  • イテレータ回してる最中に要素を削除したり追加したりすると悲しくなるので、そういうことしたいなら、あらかじめ copy メッセージ送ってコンテナをまるっとコピーしておけと*1
外部イテレータ

内部イテレータの方が記述がコンパクトだけど、処理を外部から制御したいときだってある。そういう場合は「進む」「戻る」という概念を外に出して、積極的に制御を外部に取り出してやる。これが外部イテレータ

  • Smalltalk の場合には Collection のサブクラスである Stream が外部イテレータとして使える。
    • ←2011.02.17 追記:Stream は内部イテレータである do: メッセージもサポートしていますが、クラス階層としては Collection のサブクラスにいるわけではありません。
    • non-Smalltalker 的には、Stream はファイルなんかの抽象概念ですよ、といえばいいのか。C# なんかにもあったっけ。
  • Smalltalk では String は Character の Stream なので、レキサとか書くのに便利だよ。
  • テキストエディタのアンドゥ・リドゥを実現したいときなんかにも Stream を使うといいよ。

ここまで丁寧に説明して貰うと、「内部イテレータだけでいくない?」という疑問がちょっと解消されるよね。


今 DPSC の Adaptor パターンを読み中なんだけど、こっちもすっげぇ面白い。早く追いつきたいよう。


でも今日はこれでおしまい!
ごめんなさい。

*1:空間効率いかにも悪そうだけど、オブジェクトを Copy On Write しとけば済む話なのかな。←2011.02.17 追記:Shallow Copyなのでそれほど重くないそうです。やっぱそうですよね。