Talking About Fluent Interface

111
http://www.flickr.com/photos/mio-spr/2042538806 2008‐11‐19(Wed); AppleStore, Sapporo Ruby Sapporo Night vol.8 Fluent interface について少し Talking about “Fluent interface” 島田 浩二 SHIMADA Koji; Nihon Ruby-no-kai; RubySapporo snoozer.05@ruby‐sapporo.org 日本Rubyの会/Ruby札幌

Transcript of Talking About Fluent Interface

Page 1: 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札幌

Page 2: Talking About Fluent Interface

それでは、よい設計を。

Ken Pugh 著, 角谷信太郎 監訳「インターフェイス指向設計」監訳者まえがきより

Page 3: Talking About Fluent Interface

アジェンダ✓動機✓ 2種類の利用者✓ 3つの車輪✓ 1つの視点✓まとめ

Page 4: Talking About Fluent Interface

動機

Page 5: Talking About Fluent Interface

http://rubyconf.org/

RubyConf 2008

Page 9: Talking About Fluent Interface

?メソッドチェーンとの違いは?

DSLとはどう違うのか?

Page 10: Talking About Fluent Interface

うまく説明できない

Page 11: Talking About Fluent Interface

きちんと理解したい

Page 12: Talking About Fluent Interface

✓ “気持ちよく書けるもの” 程度の漠然とした理解しかなかった

✓メソッドチェーンやDSLとの違い、関係をきちんと理解したい

動機

Page 13: Talking About Fluent Interface

http://www.flickr.com/photos/quanle/251201209/

Fluent interface :流れるようなインターフェイス

Page 15: Talking About Fluent Interface

http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface

Martinfowler’s Biki

Page 16: Talking About Fluent Interface

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));

Page 17: Talking About Fluent Interface

✓ 流れるようなアクションで特定の文脈を表現

✓ 読みやすさを第一にインターフェイスを設計

✓ 慣習 << 流れるようなスタイル

Fluent interface

Page 18: Talking About Fluent Interface

?メソッドチェーンとの違いは?

DSLとはどう違うのか?

Page 19: Talking About Fluent Interface

まだはっきりしない

Page 20: Talking About Fluent Interface

もう少し深く潜る

Page 21: Talking About Fluent Interface

http://www.flickr.com/photos/srijith/1867095482

“Fluent”流れるような

Page 22: Talking About Fluent Interface

流れるようなインターフェイス

✓何に対して?✓何が流れる?

Page 23: Talking About Fluent Interface

対象

Page 24: Talking About Fluent Interface

インターフェイスの利用者

Page 25: Talking About Fluent Interface

2種類

Page 26: Talking About Fluent Interface

インターフェイスの利用者

✓コードを書く人✓コードを読む人

Page 27: Talking About Fluent Interface

流れるもの

Page 28: Talking About Fluent Interface

個別に考える

Page 29: Talking About Fluent Interface

http://www.flickr.com/photos/mdd/175282811

コードを書く人

Page 30: Talking About Fluent Interface

コードを書く人は、

✓実現したいことに関するコンテキストを持っている

✓コンテキストの一部をインターフェイスを利用して表現しようとしている

Page 31: Talking About Fluent Interface

コードを書く人にとって、

✓流れ: コンテキストの一部⇒コードへの変換

✓流れるような: 表現したい順に手を動かしていける

Page 32: Talking About Fluent Interface

http://www.flickr.com/photos/ozyman/443545349

コードを読む人

Page 33: Talking About Fluent Interface

コードを読む人は、

✓コンテキストを通してコードを見ているとは限らない

✓処理を理解すると共に、コンテキストに関する情報を集めている

Page 34: Talking About Fluent Interface

コードを読む人にとって、

✓流れ: コード⇒していること+コンテキストの情報

✓流れるような: 目で追う順に情報を理解していける

Page 35: Talking About Fluent Interface

整理

Page 36: Talking About Fluent Interface

読んだことが流れるように頭に入ってくる

考えたことを流れるようにコードにすることが出来る

コード

Fluent interfaceが生み出したい“流れ”

インターフェイス利用者

Page 37: Talking About Fluent Interface

Fluent interface✓ 流れるようなアクションで特定の文脈を表現

✓ 読みやすさを第一にインターフェイスを設計

✓ 慣習 << 流れるようなスタイル

Page 38: Talking About Fluent Interface

少し近づけたような

Page 39: Talking About Fluent Interface

続けて道具立てについて

Page 40: Talking About Fluent Interface

http://www.flickr.com/photos/fuckr/91530309

“Interface”インターフェイス

Page 41: Talking About Fluent Interface

流れるようなインターフェイス

✓どうやって?

Page 42: Talking About Fluent Interface

ヒント

Page 43: Talking About Fluent Interface

http://capsctrl.que.jp/kdmsnr/wiki/bliki/?FluentInterface

Martinfowler’s Biki

Page 45: Talking About Fluent Interface

なんとなくわかったこと

Page 46: Talking About Fluent Interface

Fluent interfaceの車輪

✓ メソッドチェーン✓ カスケード✓ セマンティクス

http://www.flickr.com/photos/17258892@N05/2588347668

Page 47: Talking About Fluent Interface

ひとつずつ

Page 48: Talking About Fluent Interface

http://www.flickr.com/photos/good_day/117131491/

メソッドチェーンmethod chain

Page 49: Talking About Fluent Interface

✓ メソッド呼び出しを連鎖的に繋げていき一連の処理を表現

✓ 「aの結果をbしてcしたい」✓ e.x Unixのパイプ

メソッドチェーン

Page 50: Talking About Fluent Interface

インターフェイス利用者

A B C

オブジェクト オブジェクト オブジェクト

ab

c

メソッドチェーン

aの結果をbしてcしたい

Page 51: Talking About Fluent Interface

メソッドチェーン

data.grep(/foo/).uniq.sort.join(“¥n”).display

tmp1 = data.grep(/foo/)tmp2 = tmp1.uniqtmp3 = tmp2.sorttmp4 = tmp3.join(“¥n”)tmp4.display

Page 52: Talking About Fluent Interface

大事なのは一連の処理

Page 53: Talking About Fluent Interface

http://www.flickr.com/photos/jacky83/2311687241

カスケードcascade

Page 54: Talking About Fluent Interface

✓ Smalltalkでサポートされているシンタックスシュガー

✓ 一つのオブジェクトに対する一連の処理を記述

✓ 一連のメッセージを流し込む✓ 「Aに対してaしてbしてcしたい」

カスケード

Page 55: Talking About Fluent Interface

カスケードTranscript clear.Transcript nextPutAll: ‘SHIMADA Koji’.Transcript cr.Transcript flush.

Transcript clear; nextPutAll: ‘SHIMADA Koji’; cr; flush

Page 56: Talking About Fluent Interface

インターフェイス利用者

A

オブジェクト

a

b

c

カスケード

Aにaしてbしてcしたい

Page 57: Talking About Fluent Interface
Page 58: Talking About Fluent Interface

✓ Javaでは言語としてカスケードをサポートしていなかった

✓ 自分自身を返り値とすれば、メソッドチェーンで実現することができる

✓ 慣習には背くけど

カスケード

Page 59: Talking About Fluent Interface

カスケードexpectation.setCount(once());expectation.setMethod(“buy”);expectation.setArgument(eq(QUANTITY));expectation.setResult(TICKET);

expectation.setCount(once()) .setMethod(“buy”) .setArgument(eq(QUANTITY)); .setResult(TICKET);

Page 60: Talking About Fluent Interface

大事なのは一連の処理

Page 61: Talking About Fluent Interface

http://www.flickr.com/photos/mio-spr/428995450

セマンティクスsemantics

Page 62: Talking About Fluent Interface

最も重要

Page 63: Talking About Fluent Interface

✓ 実現手段ではなく、意図を伝えるメソッド名をつける

✓ それ単体では利用者に価値を生み出さない操作をどうするか?  ⇒シンタックスとしてしまう

✓ 利用者に価値を生み出す単位で、操作の意図が伝わることが重要

セマンティクスを表現する

Page 64: Talking About Fluent Interface

JMock API

mainframe.expects(once()) .method(“buy”).with(eq(QUANTITY)) .will(returnValue(TICKET));

expectation.setCount(once()) .setMethod(“buy”) .setArgument(eq(QUANTITY)); .setResult(TICKET);

Page 65: Talking About Fluent Interface

コ、コイツ読めるぞ…

Page 66: Talking About Fluent Interface

data.grep(/foo/).uniq.sort.join(“¥n”).display

それ単体でも利用者にとって価値のある操作は、そのままでも十分意図が伝わる

セマンティクスを表現する

(1..10).map{|i| i*i}.select{|i| i % 2 == 0}

Page 67: Talking About Fluent Interface

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));

Page 68: Talking About Fluent Interface

大事なのは利用者に価値のある単位

Page 69: Talking About Fluent Interface

Fluent interfaceの車輪

✓ メソッドチェーン✓ カスケード✓ セマンティクス

http://www.flickr.com/photos/17258892@N05/2588347668

Page 70: Talking About Fluent Interface

Fluent interface✓ 流れるようなアクションで特定の文脈を表現

✓ 読みやすさを第一にインターフェイスを設計

✓ 慣習 << 流れるようなスタイル

Page 71: Talking About Fluent Interface

簡単なサンプル

Page 72: Talking About Fluent Interface

rate = Discount.newrate.cash = 0.05rate.membership = 0.02rate.price = 0.01product.apply_discount(rate)

Page 73: Talking About Fluent Interface

product.apply( Discount.for. cash(0.05). membership(0.02). price(0.01))

Page 74: Talking About Fluent Interface

class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend

Page 75: Talking About Fluent Interface

class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend

Page 76: Talking About Fluent Interface

class Discount ... def Discount.for Discount.new end def cash(discount) @for_cash = discount self endend

Page 77: Talking About Fluent Interface

class Product ... def apply(discount) @discount = discount end ...end

Page 78: Talking About Fluent Interface

product.apply( Discount.for. cash(0.05). membership(0.02). price(0.01))

Page 79: Talking About Fluent Interface

やってみて感じたこと

Page 80: Talking About Fluent Interface

大事なことはあまり変わらない

Page 81: Talking About Fluent Interface

✓責務の振り分け✓返り値✓引数✓メソッド名

Page 82: Talking About Fluent Interface
Page 83: Talking About Fluent Interface
Page 84: Talking About Fluent Interface

Page 85: Talking About Fluent Interface

http://www.flickr.com/photos/srijith/1867095482

流れ

Page 86: Talking About Fluent Interface

読んだことが流れるように頭に入ってくる

考えたことを流れるようにコードにすることが出来る

コード

Fluent interfaceが生み出したい“流れ”

インターフェイス利用者

Page 87: Talking About Fluent Interface

読んだことが流れるように頭に入ってくる

考えたことを流れるようにコードにすることが出来る

コード

Fluent interfaceが生み出したい“流れ”

インターフェイス利用者

Page 88: Talking About Fluent Interface

読んだことが流れるように頭に入ってくる

考えたことを流れるようにコードにすることが出来る

コード

Fluent interfaceが生み出したい“流れ”

インターフェイス利用者

Page 89: Talking About Fluent Interface

読んだことが流れるように頭に入ってくる

考えたことを流れるようにコードにすることが出来る

コード

Fluent interfaceが生み出したい“流れ”

インターフェイス利用者

Page 90: Talking About Fluent Interface

Fluent interfaceという観点でインターフェイスを見つめる行為は、インターフェイスの具体的な利用者のことを強く考えさせてくれる

Page 91: Talking About 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」

Page 92: Talking About Fluent Interface

Fluent interfaceはインターフェイスも人に向けて書かれるべきだと改めて教えてくれている

http://www.flickr.com/photos/suvcougar/

Page 93: Talking About Fluent Interface

飛躍

Page 94: Talking About Fluent Interface

インターフェイス設計に動線というメタファを持ってこれないだろうか

Page 95: Talking About Fluent Interface

動線

Page 96: Talking About Fluent Interface

動線✓ 建物の中を、人が自然に動く時に通ると思われる径路

✓ 建物の間取りをするときに気をつけるべきこと

✓ 設計の際に利用者の行動パターンを予測し、より明快に、また移動距離が長くならないよう考慮する

http://ja.wikipedia.org/wiki/%E5%8B%95%E7%B7%9A

Page 97: Talking About Fluent Interface

利用者の行動パターンを予測し、より明快に、移動距離を短く

Page 98: Talking About Fluent Interface

勉強中

Page 99: Talking About Fluent Interface

http://www.flickr.com/photos/storm-crypt/2280100565

どうやって見つけるか

Page 100: Talking About Fluent Interface
Page 101: Talking About Fluent Interface

これまでの作業は机の上でできています。確かに現場の条件をよーく考慮して、このスケッチは出来ています。でも気をつけて下さい! これは、あくまで、机の上の「絵」にすぎません。現場で、直接、原寸で、絵を描いて、はじめてリアルな形となるのです。

Page 102: Talking About Fluent Interface

動線の見つけ方

Page 103: Talking About Fluent Interface

どうやって見つけるか

✓ TDD✓ テストコードが最初の利用者✓インクリメンタルな開発✓ こまめにリリースすることで実際の利用者からフィードバックを受ける

Page 104: Talking About Fluent Interface

http://www.flickr.com/photos/nibaq/1735007

学び方

Page 105: Talking About Fluent Interface

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)

Page 106: Talking About Fluent Interface

まとめ

Page 107: Talking About Fluent Interface

✓ 2種類の利用者✓ コードを読む、コードを書く✓ 3つの車輪✓ メソッドチェーン、カスケード、セマンティクス

✓ 1つの視点✓ 利用者に価値があるかどうか

ここまでのまとめ

Page 108: Talking About Fluent Interface

“インターフェイスに対してプログラミングするのであって,実装に対してプログラミングするのではない” (GoF)

Page 109: Talking About Fluent Interface

より良いインターフェイスを探求する僕らの冒険はまだ始まったばかり

http://www.flickr.com/photos/pedrosz/2287112249

Page 110: Talking About Fluent Interface

未完

Page 111: 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札幌