以前から気になっていた FactoryBuilderSupport をあれこれイジっていきます。
Groovy で独自のビルダーを作る場合 BuilderSupport クラスのサブクラスを作成するのが一般的かと思いますが、ある程度込み入ったものを作りたいときにはちょっと役者不足。 そういう場合にはノードごとにファクトリを対応させてオブジェクトを構築できる FactoryBuilderSupport の出番。 FactoryBuilderSupport クラスはもともと SwingBuilder の実装に使われていたものだそうですが、独自ビルダーの作成に便利なため、汎用性がある部分を抽出してクラスにされたようです。 ちなみに Griffon の UberBuilder にも使用されています。
FactoryBuilderSupport は通常(groovy.util パッケージの) Factory インターフェースや AbstractFactory クラスとともに用いるものですが、それは後日にまわして、今回は FactoryBuilderSupport の簡単な動かし方だけ見ていきます(動作確認 Groovy 1.8.0)。
参考 URL
- 「FactoryBuilderSupport」
- 「GroovyDoc for Groovy and Java classes」 FactoryBuilderSupport
- 「Groovy for Domain-Specific Languages」 FactoryBuilderSupport
ビルダーの実装
まずは構築対象の Bean クラス。 いくつか適当にプロパティを定義してあります:
@groovy.transform.ToString class MathGirl { String name int age String ability }
これを踏まえて、MathGirl オブジェクトを構築するビルダーを作りましょう。 FactoryBuilderSupport クラスは抽象クラスですが抽象メソッドは定義されていないため、サブクラスを作るために何らかのメソッドを実装しないといけないというわけではありませんが、ノードからオブジェクトを生成する何らかのファクトリ (groovy.util.Factory) を登録する必要があります。 独自のロジックでオブジェクトを生成するファクトリは後日試すことにして、今回は Bean クラスを簡単にインスタンス化できるものを作ります。
class MathGirlBuilder extends FactoryBuilderSupport{ MathGirlBuilder(){ // 'mathGirl' というノードに MathGirl クラスの Bean ファクトリを登録 registerBeanFactory('mathGirl', MathGirl) } }
ここでは 'mathGirl' というノードから MathGirl クラスのオブジェクトを生成するようにしています。 このビルダーを使って、実際にオブジェクトの構築を行ってみましょう。 大体、こんな感じのビルド方法があります:
- 基本ビルド
- スクリプトからビルド
2番目の方法は build() メソッドを使います。 他に withBuilder() メソッドってのもありますが、まだあんまり使い方理解してないのでスルー*1。
基本ビルド
まずは基本的なビルダーの使い方。 手順は
- ビルダーのインスタンス取得
- ビルダーに対するメソッド呼び出しでオブジェクトを構築
です。
// 1. ビルダーのインスタンス取得 def builder = new MathGirlBuilder() // 2. ビルダーに対するメソッド呼び出しでオブジェクトを構築 def milka = builder.mathGirl(name:'Milka', age:17, ability:'Mathematics') assert milka.toString() == 'MathGirl(Milka, 17, Mathematics)'
Bean ファクトリはノードに渡された属性(今の場合 name, age, ability)を自動で Bean オブジェクトに注入してくれます。 ただ、Bean ファクトリはクロージャ(ネストノード)が使えないので、これだけだとあんまり有難味が感じられないけど・・・ まぁお楽しみは次回以降に。
スクリプトからビルド
スクリプトからビルドを行いたい場合、FactoryBuilderSupport クラスの build() メソッドを使います。 このメソッドがとれる引数は
- Class オブジェクト
- Script オブジェクト
の2つです。
Class オブジェクトからビルド
まずは Class オブジェクトからビルドを実行する方法。 このクラスは Groovy スクリプトをコンパイルしてできた Script のサブクラスです。 たとえば以下のような Groovy スクリプト(ファイル名 TetoraScript.groovy)
// TetoraScript.groovy mathGirl(name:'Tetora', age:16, ability:'English')
をコンパイルしてできたクラス TetoraScript があるとすると、
def builder = new MathGirlBuilder() def tetora = builder.build(TetoraScript.class) // def tetora = builder.build(TetoraScript) でも OK assert tetora == 'MathGirl(Tetora, 16, English)'
のようにして、オブジェクトを構築することができます。
Script オブジェクトからビルド
次は Script オブジェクトからビルドを実行する方法。
// Script オブジェクト生成 def shell = new GroovyShell() def script = shell.parse('''mathGirl(name:'Yuri', age:14, ability:'Logic')''') // 以下、ビルドの実行 def builder = new MathGirlBuilder() def yuri = builder.build(script) assert yuri.toString() == 'MathGirl(yuri, 14, Logic)'
GroovyShell を使って Script オブジェクトを生成してます。 まぁ、改めて書くほどのものでもなかったかな。 次回はファクトリを作る予定。
Groovy for Domain-specific Languages
- 作者: Fergal Dearle
- 出版社/メーカー: Packt Publishing
- 発売日: 2010/05/30
- メディア: ペーパーバック
- この商品を含むブログ (9件) を見る
数学ガール ゲーデルの不完全性定理 (数学ガールシリーズ 3)
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2009/10/27
- メディア: ペーパーバック
- 購入: 37人 クリック: 930回
- この商品を含むブログ (153件) を見る