{cdate:2010-01-26}
{what:groovy,closure,dsl}

  1. 条件判定にクロージャを利用 groovy

> さらにこのコードを見直したエントリーはこちら(クロージャを使って2点間の関係について調べるコードを書く)(closure.html)

たとえば、無数の点が平面上に存在していて、
その点と点の関係を調べてグループ分けしたい、という問題を解く場合。

考えられるグループは...

などが考えられます。

点に対するグループの分け方ルールは無数に存在するので、
思いつきでどんどんルールを追加・変更できるように設計しておきたい。

こういう場合に、普通のJava的発想では、
点同士の関係を解析する IAnalyzer インターフェスを定義して...
という発想になってしまうのですが、
GroovyのClosureを使えばもっとスマートに速く問題を解決できそうです。

    1. Closureでルールを定義していく
      1. コード mypoint.groovy

{codeinclude:closure-1/mypoint.groovy}

      1. 実行

{console}
$ groovy mypoint.groovy
横に並んでいるいるか? -> false
すぐ下にあるか? -> true
{console}

      1. 説明

MyPoint という点(x,y)を保持したクラスを用意し、
そこに、*と次の点を調べる* という MyPointとClosureを引数に持つメソッドを定義するだけ。
あとは、groovy スクリプトで、点と点に関するルールを書いたクロージャを
思いついた段階でどんどん書いていけばよい。

興味深いのはコード自体が処理内容の説明になっている点。
たとえば、MyPoint のインスタンス point1 と point2 が完全に重なった点かどうかを調べるには...


def 結果 = point1.と次の点を調べる(point2) { p1,p2-> (p1.x==p2.x && p1.y==p2.y) }

と書けばよい。
もし、この重なった点かどうかを調べるクロージャを再利用したいならば...


def 2つの点は重なっているか = {p1,p2-> (p1.x==p2.x && p1.y==p2.y) }

と定義しておいてから、


def 結果 = point1.と次の点を調べる( point2, 2つの点は重なっているか )
println 結果

とすればよい。プログラムがそのまま自分自身の処理の説明になっている点がすごい。