Talking About Fluent Interface
-
Upload
koji-shimada -
Category
Technology
-
view
2.340 -
download
6
Transcript of Talking About Fluent Interface
http://www.flickr.com/photos/mio-spr/2042538806
2008‐11‐19(Wed); AppleStore, SapporoRuby Sapporo Night vol.8
Fluent interfaceについて少しTalking about “Fluent interface”
島田 浩二SHIMADA Koji; Nihon Ruby-no-kai; RubySapporo
snoozer.05@ruby‐sapporo.org
日本Rubyの会/Ruby札幌
それでは、よい設計を。
Ken Pugh 著, 角谷信太郎 監訳「インターフェイス指向設計」監訳者まえがきより
アジェンダ✓動機✓ 2種類の利用者✓ 3つの車輪✓ 1つの視点✓まとめ
動機
http://www.nealford.com/downloads/conferences/canonical/Neal_Ford-Advanced_DSLs_in_Ruby-slides.pdf
Neal Ford,Advanced DSL in Ruby
http://www.nealford.com/downloads/conferences/canonical/Neal_Ford-Advanced_DSLs_in_Ruby-slides.pdf
Neal Ford,Advanced DSL in Ruby
http://www.nealford.com/downloads/conferences/canonical/Neal_Ford-Advanced_DSLs_in_Ruby-slides.pdf
Neal Ford,Advanced DSL in Ruby
?メソッドチェーンとの違いは?
DSLとはどう違うのか?
うまく説明できない
きちんと理解したい
✓ “気持ちよく書けるもの” 程度の漠然とした理解しかなかった
✓メソッドチェーンやDSLとの違い、関係をきちんと理解したい
動機
http://www.flickr.com/photos/quanle/251201209/
Fluent interface :流れるようなインターフェイス
http://www.flickr.com/photos/jw3000/12703492
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface
Martinfowler’s Biki
JMock APIExpect.Once.On(mockLogger) .Method(“LogError”) .With(Has.Substring(USER_NAME) & Has.Substring(“access defined”));
mainframe.expects(once()) .method(“buy”).with(eq(QUANTITY)) .will(returnValue(TICKET));
✓ 流れるようなアクションで特定の文脈を表現
✓ 読みやすさを第一にインターフェイスを設計
✓ 慣習 << 流れるようなスタイル
Fluent interface
?メソッドチェーンとの違いは?
DSLとはどう違うのか?
まだはっきりしない
もう少し深く潜る
http://www.flickr.com/photos/srijith/1867095482
“Fluent”流れるような
流れるようなインターフェイス
✓何に対して?✓何が流れる?
対象
インターフェイスの利用者
2種類
インターフェイスの利用者
✓コードを書く人✓コードを読む人
流れるもの
個別に考える
http://www.flickr.com/photos/mdd/175282811
コードを書く人
コードを書く人は、
✓実現したいことに関するコンテキストを持っている
✓コンテキストの一部をインターフェイスを利用して表現しようとしている
コードを書く人にとって、
✓流れ: コンテキストの一部⇒コードへの変換
✓流れるような: 表現したい順に手を動かしていける
http://www.flickr.com/photos/ozyman/443545349
コードを読む人
コードを読む人は、
✓コンテキストを通してコードを見ているとは限らない
✓処理を理解すると共に、コンテキストに関する情報を集めている
コードを読む人にとって、
✓流れ: コード⇒していること+コンテキストの情報
✓流れるような: 目で追う順に情報を理解していける
整理
読んだことが流れるように頭に入ってくる
考えたことを流れるようにコードにすることが出来る
コード
Fluent interfaceが生み出したい“流れ”
インターフェイス利用者
Fluent interface✓ 流れるようなアクションで特定の文脈を表現
✓ 読みやすさを第一にインターフェイスを設計
✓ 慣習 << 流れるようなスタイル
少し近づけたような
続けて道具立てについて
http://www.flickr.com/photos/fuckr/91530309
“Interface”インターフェイス
流れるようなインターフェイス
✓どうやって?
ヒント
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface
Martinfowler’s Biki
Evolving an EDSL in Java
http://www.mockobjects.com/files/evolving_an_edsl.ooplsa2006.pdf
なんとなくわかったこと
Fluent interfaceの車輪
✓ メソッドチェーン✓ カスケード✓ セマンティクス
http://www.flickr.com/photos/17258892@N05/2588347668
ひとつずつ
http://www.flickr.com/photos/good_day/117131491/
メソッドチェーンmethod chain
✓ メソッド呼び出しを連鎖的に繋げていき一連の処理を表現
✓ 「aの結果をbしてcしたい」✓ e.x Unixのパイプ
メソッドチェーン
インターフェイス利用者
A B C
オブジェクト オブジェクト オブジェクト
ab
c
メソッドチェーン
aの結果をbしてcしたい
メソッドチェーン
data.grep(/foo/).uniq.sort.join(“¥n”).display
tmp1 = data.grep(/foo/)tmp2 = tmp1.uniqtmp3 = tmp2.sorttmp4 = tmp3.join(“¥n”)tmp4.display
大事なのは一連の処理
http://www.flickr.com/photos/jacky83/2311687241
カスケードcascade
✓ Smalltalkでサポートされているシンタックスシュガー
✓ 一つのオブジェクトに対する一連の処理を記述
✓ 一連のメッセージを流し込む✓ 「Aに対してaしてbしてcしたい」
カスケード
カスケードTranscript clear.Transcript nextPutAll: ‘SHIMADA Koji’.Transcript cr.Transcript flush.
Transcript clear; nextPutAll: ‘SHIMADA Koji’; cr; flush
インターフェイス利用者
A
オブジェクト
a
b
c
カスケード
Aにaしてbしてcしたい
✓ Javaでは言語としてカスケードをサポートしていなかった
✓ 自分自身を返り値とすれば、メソッドチェーンで実現することができる
✓ 慣習には背くけど
カスケード
カスケードexpectation.setCount(once());expectation.setMethod(“buy”);expectation.setArgument(eq(QUANTITY));expectation.setResult(TICKET);
expectation.setCount(once()) .setMethod(“buy”) .setArgument(eq(QUANTITY)); .setResult(TICKET);
大事なのは一連の処理
http://www.flickr.com/photos/mio-spr/428995450
セマンティクスsemantics
最も重要
✓ 実現手段ではなく、意図を伝えるメソッド名をつける
✓ それ単体では利用者に価値を生み出さない操作をどうするか? ⇒シンタックスとしてしまう
✓ 利用者に価値を生み出す単位で、操作の意図が伝わることが重要
セマンティクスを表現する
JMock API
mainframe.expects(once()) .method(“buy”).with(eq(QUANTITY)) .will(returnValue(TICKET));
expectation.setCount(once()) .setMethod(“buy”) .setArgument(eq(QUANTITY)); .setResult(TICKET);
コ、コイツ読めるぞ…
data.grep(/foo/).uniq.sort.join(“¥n”).display
それ単体でも利用者にとって価値のある操作は、そのままでも十分意図が伝わる
セマンティクスを表現する
(1..10).map{|i| i*i}.select{|i| i % 2 == 0}
data.grep(/foo/).uniq.sort.join(“¥n”).display
セマンティクスを表現する
(1..10).map{|i| i*i}.select{|i| i % 2 == 0}
mainframe.expects(once()) .method(“buy”).with(eq(QUANTITY)) .will(returnValue(TICKET));
大事なのは利用者に価値のある単位
Fluent interfaceの車輪
✓ メソッドチェーン✓ カスケード✓ セマンティクス
http://www.flickr.com/photos/17258892@N05/2588347668
Fluent interface✓ 流れるようなアクションで特定の文脈を表現
✓ 読みやすさを第一にインターフェイスを設計
✓ 慣習 << 流れるようなスタイル
簡単なサンプル
rate = Discount.newrate.cash = 0.05rate.membership = 0.02rate.price = 0.01product.apply_discount(rate)
product.apply( Discount.for. cash(0.05). membership(0.02). price(0.01))
class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend
class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend
class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend
class Product ... def apply(discount) @discount = discount end ...end
product.apply( Discount.for. cash(0.05). membership(0.02). price(0.01))
やってみて感じたこと
大事なことはあまり変わらない
✓責務の振り分け✓返り値✓引数✓メソッド名
+α
http://www.flickr.com/photos/srijith/1867095482
流れ
読んだことが流れるように頭に入ってくる
考えたことを流れるようにコードにすることが出来る
コード
Fluent interfaceが生み出したい“流れ”
インターフェイス利用者
読んだことが流れるように頭に入ってくる
考えたことを流れるようにコードにすることが出来る
コード
Fluent interfaceが生み出したい“流れ”
インターフェイス利用者
読んだことが流れるように頭に入ってくる
考えたことを流れるようにコードにすることが出来る
コード
Fluent interfaceが生み出したい“流れ”
インターフェイス利用者
読んだことが流れるように頭に入ってくる
考えたことを流れるようにコードにすることが出来る
コード
Fluent interfaceが生み出したい“流れ”
インターフェイス利用者
Fluent interfaceという観点でインターフェイスを見つめる行為は、インターフェイスの具体的な利用者のことを強く考えさせてくれる
...a programmer’s job is too communicatewith other programmers, not just a machine.
Programming, then, is a human task done by humans for humans.
Oh, and writing good code at the same time.
プログラムは、マシンにだけではなく、自分以外のプログラマに向けて書かれるべきなんだ。
そうすることで、プログラミングは人による、人のための、人の仕事になる。
もちろん、それは良いコードにもなっているんだよ。
- Kent Beck「Implementation Patterns」
Fluent interfaceはインターフェイスも人に向けて書かれるべきだと改めて教えてくれている
http://www.flickr.com/photos/suvcougar/
飛躍
インターフェイス設計に動線というメタファを持ってこれないだろうか
動線
動線✓ 建物の中を、人が自然に動く時に通ると思われる径路
✓ 建物の間取りをするときに気をつけるべきこと
✓ 設計の際に利用者の行動パターンを予測し、より明快に、また移動距離が長くならないよう考慮する
http://ja.wikipedia.org/wiki/%E5%8B%95%E7%B7%9A
利用者の行動パターンを予測し、より明快に、移動距離を短く
勉強中
http://www.flickr.com/photos/storm-crypt/2280100565
どうやって見つけるか
これまでの作業は机の上でできています。確かに現場の条件をよーく考慮して、このスケッチは出来ています。でも気をつけて下さい! これは、あくまで、机の上の「絵」にすぎません。現場で、直接、原寸で、絵を描いて、はじめてリアルな形となるのです。
動線の見つけ方
どうやって見つけるか
✓ TDD✓ テストコードが最初の利用者✓インクリメンタルな開発✓ こまめにリリースすることで実際の利用者からフィードバックを受ける
http://www.flickr.com/photos/nibaq/1735007
学び方
Fluent interface in wild✓ named_scope✓ User.not_admin.age(10..20)
✓ RSpec✓ user.active.should be_all {|u| not u.deleted }
✓ ActiveSupport✓ Date.parse('2008-11-19').yesterday.ago(1.second)
まとめ
✓ 2種類の利用者✓ コードを読む、コードを書く✓ 3つの車輪✓ メソッドチェーン、カスケード、セマンティクス
✓ 1つの視点✓ 利用者に価値があるかどうか
ここまでのまとめ
“インターフェイスに対してプログラミングするのであって,実装に対してプログラミングするのではない” (GoF)
より良いインターフェイスを探求する僕らの冒険はまだ始まったばかり
http://www.flickr.com/photos/pedrosz/2287112249
未完
http://www.flickr.com/photos/mio-spr/2042538806
2008‐11‐19(Wed); AppleStore, SapporoRuby Sapporo Night vol.8
Fluent interfaceについて少しTalking about “Fluent interface”
島田 浩二SHIMADA Koji; Nihon Ruby-no-kai; RubySapporo
snoozer.05@ruby‐sapporo.org
日本Rubyの会/Ruby札幌