流れるようなインターフェースって結局ビルダなのね
今更感溢れる話題だけど、Ruby でキーワード引数的な Fluent Interface の実装 - 8時40分が超えられない - subtechの違和感が非常に気になったのでちょっと考えてみた。
まず、違和感のないものを考える
TimeInterval meetingTime = fiveOClock.until(sixOClock);Martin Fowler's Bliki in Japanese - 流れるようなインターフェース
Ruby脳なので、これは普通すぎて別に流れてないと思った。
private void makeFluent(Customer customer) { customer.newOrder() .with(6, "TAL") .with(5, "HPK").skippable() .with(3, "LGV") .priorityRush(); }Martin Fowler's Bliki in Japanese - 流れるようなインターフェース
これって、要するにCustomerに追加するOrderビルダのsetterメソッドチェインだよね。
List<Employee> results = jdbcManager.from(Employee.class) .join("department") .where("name like ?", "S%") .orderBy("name") .getResultList();流れるようなインターフェースと脱CoC - ひがやすを blog
これも、orderByまでを「SQLクエリのビルダ」と考えると自然になる。
違和感のあるものに戻ってくる
fluent = FluentInterface.fluent WEBrick::HTTPServer, :new server = fluent.DocumentRoot('/var/www').BindAddress('0.0.0.0').Port(8001).execute server.startRuby でキーワード引数的な Fluent Interface の実装 - 8時40分が超えられない - subtech
上記を踏まえると、これもビルダとして考えるのが自然だと思う。
メソッドに対し、特定の引数を固定したメソッドを返す……あれ? これって要するに単なる部分適用?
そう考えると、上記の後に書かれてるメソッド組み立てのほうが違和感は減る。
fluent = FluentInterface.fluent WEBrick::HTTPServer, :new fluent = fluent.DocumentRoot('/var/www').Port(8001) fluent = fluent.BindAddress('0.0.0.0') server = fluent.executeRuby でキーワード引数的な Fluent Interface の実装 - 8時40分が超えられない - subtech
1行目でメソッドを取り出し、2〜3行目で部分適用し、その結果のメソッドを再代入し、4行目で実行する*1。うん、自然だ!*2