Qi4j を使ったコンポジット指向プログラミング
Qi4j を使ったコンポジット指向プログラミングでは、複数のオブジェクトを組み合わせた(mixin)、コンポジットを作成し、実行時に決定されるレイヤーやモジュールという構成内でコンポジットを扱えるようになっている。
今回は、以下のような手順で Qi4j アプリケーションを試してみた。
- Maven2 でプロジェクト作成
- pom.xml に Qi4j用のリモートリポジトリと依存設定追加
- ドメインインターフェース作成
- ドメインインターフェースの実装クラス(Mixin クラス)作成
- コンポジットの定義
- 実行クラスの作成と動作確認
Maven2 でプロジェクト作成
今回は Java アプリケーションで動作確認するため、Maven2 で archetype:create を使った一般的なプロジェクトを作成。
プロジェクト作成例
>mvn archetype:create -DgroupId=fits.sample -DartifactId=sample1
pom.xml に Qi4j用のリモートリポジトリと依存設定追加
自動生成された pom.xml ファイルに以下のような設定を行い、Qi4j を使用できるようにする。
リポジトリの設定は以下の通り。
リポジトリ設定
<repository> <id>org.qi4j</id> <name>Qi4j Repository</name> <url>http://repository.ops4j.org/maven2/</url> </repository>
今回は基本的な API を試すだけなので以下の依存ライブラリ設定のみ追加。
依存ライブラリ設定
<dependency> <groupId>org.qi4j.core</groupId> <artifactId>qi4j-core-runtime</artifactId> <version>0.7</version> </dependency>
動作確認用に Java の指定クラスを実行するプラグインの設定を追加し、最終的に以下のような pom.xml ファイルを用意した。
pom.xml の設定例
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>fits.sample</groupId> <artifactId>qi4jsample1</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>qi4jsample1</name> <dependencies> <dependency> <groupId>org.qi4j.core</groupId> <artifactId>qi4j-core-runtime</artifactId> <version>0.7</version> </dependency> </dependencies> <repositories> <repository> <id>org.qi4j</id> <name>Qi4J Repository</name> <url>http://repository.ops4j.org/maven2/</url> </repository> </repositories> <build> <plugins> <!-- Java 1.5 用にコンパイルするための設定 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <!-- mvn exec:java で指定のクラスを実行するプラグイン --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <configuration> <executable>java</executable> <mainClass>fits.sample.App</mainClass> </configuration> </plugin> </plugins> </build> </project>
ドメインインターフェース作成
Qi4j では、コンポジットの構成要素とする機能毎にドメインインターフェースを用意し、ドメインインターフェースの実装クラス(Mixin クラス)をコンポジットに組み込むような作り方をするので、まずドメインインターフェースを作成する。
ドメインインターフェースは普通の Java インターフェースを用意するだけ。
Sample.java
package fits.sample; public interface Sample { String hello(String msg); }
ドメインインターフェースの実装クラス(Mixin クラス)作成
ドメインインターフェースの実装クラスを作成する。こちらも特別な事をする必要はない。
package fits.sample; public class SampleMixin implements Sample { public String hello(String msg) { return "hello, " + msg; } }
コンポジットの定義
コンポジットはドメインインターフェースと Composite インターフェースを継承したインターフェースとして定義し、@Mixins アノテーションで実装クラス(Mixin クラス)を指定する。(実際は複数のドメインインターフェースと Mixin クラスを設定してコンポジットを定義する事になる)
SampleComposite.java
package fits.sample; import org.qi4j.api.composite.Composite; import org.qi4j.api.mixin.Mixins; @Mixins({SampleMixin.class}) public interface SampleComposite extends Sample, Composite { }
実行クラスの作成と動作確認
今回は、単一レイヤーの単一モジュールで Qi4j アプリケーションを構成する SingletonAssembler を使って動作確認を実施した。
App.java
package fits.sample; import org.qi4j.api.composite.CompositeBuilderFactory; import org.qi4j.bootstrap.SingletonAssembler; import org.qi4j.bootstrap.ModuleAssembly; import org.qi4j.bootstrap.AssemblyException; public class App { public static void main( String[] args ) { SingletonAssembler ass = new SingletonAssembler() { public void assemble(ModuleAssembly module) throws AssemblyException { module.addComposites(SampleComposite.class); } }; CompositeBuilderFactory factory = ass.compositeBuilderFactory(); //コンポジットの作成 Sample sample = factory.newComposite(Sample.class); System.out.println(sample.hello("test")); } }
動作確認
>mvn compile >mvn exec:java ・・・ hello, test ・・・