今回はやっとネスト構造を構築するビルダー。 なるべく簡単なサンプルを見ていきます。
ノードを構築するスクリプト
今回は、まずビルダーでオブジェクトを構築するスクリプトから見ていきましょう。 前回までに作った MathGirl オブジェクトを構築する mathGirl ノードが使えるとして、それらを子ノードとする girls ノードから、MathGirl オブジェクトの List を構築できるようにします。 スクリプトはこんなの:
def builder = new MathGirlBuilder() // ビルダーによる構築 def girls= builder.girls{ mathGirl(name:'Milka', age:17, ability:'Mathematics') mathGirl(name:'Tetora', age:16, ability:'English') mathGirl(name:'Yuri', age:14, ability:'Logic') } assert girls.collect{ it.name }.join(', ') == 'Milka, Tetora, Yuri'
ちょっとはビルダーらしくなってきたかな。
ファクトリ・クラス
では、実際に実装していきましょう。 今回は構築するオブジェクトを List オブジェクトにするので、構築対象のクラス(前回までの Bean クラス)を新たに作る必要はなし。 なのでファクトリ・クラスを作っていきます。
ネストノードを許すファクトリ・クラスを作るにもやはり AbstractFactory クラスを継承して Factory インターフェースのサブクラスを作成します。 AbstractFactory クラスのサブクラスを作るには newInstance() メソッドを実装する必要がありましたが、ネストされたノードからオブジェクトを構築する場合には構築されたオブジェクトにも対応するネスト構造を入れる必要があるために、大抵、これに加えて
- setChild()
- setParent()
のいずれかもしくは両方を実装します。 これらのメソッドの違いは、あるノードの親子関係を考えたときに
- setChild() ・・・ 親ノードを構築するファクトリに対して呼ばれる
- setParent() ・・・ 子ノードを構築するファクトリに対して呼ばれる
となっています。 今回のサンプルでは mathGirl ノードと girls ノードに親子関係がありますが
- MathGirlFactory に対しては setParent() が呼ばれる
- GirlsFactory に対しては setChild() が呼ばれる
となります*1。 今回はGirlsFactory クラスに setChild() メソッドを実装します:
class GirlsFactory extends AbstractFactory{ @Override Object newInstance(FactoryBuilderSupport builder, name, value, Map atts) { return [] } @Override void setChild(FactoryBuilderSupport builder, node, child) { assert child instanceof MathGirl // 念のため子ノードから構築されるオブジェクトの型を確認 node << child } }
newInstance() メソッドでは単純に List オブジェクトを作成し、setChild() メソッドでは子ノードから構築された MathGirl オブジェクトをその List オブジェクトに追加しています。
ビルダーへの登録
ビルダーへの登録方法は、前回と同じく FactoryBuilderSupport#registerFactory() メソッドによって行います:
class MathGirlBuilder extends FactoryBuilderSupport{ MathGirlBuilder(){ registerBeanFactory('mathGirl', MathGirl) registerFactory('problem', new MathProblemFactory()) // GirlsFactory の登録 registerFactory('girls', new GirlsFactory()) } }
これで最初に載せたサンプルが動きます。 ネスト構造、恐るるに足らず。
Groovy for Domain-specific Languages
- 作者: Fergal Dearle
- 出版社/メーカー: Packt Publishing
- 発売日: 2010/05/30
- メディア: ペーパーバック
- この商品を含むブログ (9件) を見る
- 作者: 結城浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2007/06/27
- メディア: ペーパーバック
- 購入: 58人 クリック: 1,055回
- この商品を含むブログ (970件) を見る
*1:構築時には MathGirlFactory#setParent() → GirlsFactory#setChild() の順で呼ばれるようです。