Eclipse 4 (e4) Tutorial - Soft migration from 3.x to Eclipse 4 (e4)
(訳注: 前の回では次にDIの詳細について触れるとあったが、それは次の回に回されている?)
この連載の以前のパートでは、アプリケーションモデルを生成し、それを実装にリンクし、
アプリケーションモデルを拡張する方法、さらに依存性注入の詳細を説明しました。
このチュートリアルでは、Eclipse4 (e4)プログラミングモデルへの穏やかな移行方法を
説明します。このチュートリアルの基本的な目標は、開発において、依存性注入、アノテーションなどの新しい概念を
使えるようにすることです。
ただし、最初は完全なアプリケーションの移行は求めないこととします。そのため、3.xを要求するすべての既存のプラグインや枠組みは、いまだ以前と同じように使うことができます。
しかし、e4プログラミングモデルに沿ってアプリケーションの新たなUIコンポーネントを
開発することには、2つのアドバンテージがあります。
1. 新たなコンポーネントは、POJOであり、それゆえ自由度が高く、テストが容易で、再利用性が高いです
2. もし、アプリケーションがEclipse4アプリケーションプラットフォームに移行する場合、これらの
コンポーネントは、既にe4で使用できる状態になります。
おもしろいことに一番目に挙げたアドバンテージは、たとえ、近々にEclipse4を使うことを考えていないとしても、活用する価値があります。この考えは、実際にたいへんシンプルで特に目新しいものではありません。
3.xでのPOJO
基本的な概念は、カスタムアプリケーションに対するコードと、そのコンポーネントを
Eclipseワークベンチに組み込むためのコードを明確に分離させることです。
2つ目のグループのコードは、ワークベンチAPIに依存しており、それゆえ、Eclipseのバージョンすなわち、3.xや4.xに特化したものになります。1つ目のグループのコードは、Eclispeのバージョンに依存させる必要はありません。
事実、ワークベンチのことは少しも知る必要がないのです。
このような分離の良い例として、ハンドラの実装を挙げることができます。ハンドラを実装するために、Eclipse 3.xでは、ハンドラはコマンドに結び付けられ、
IHandlerインタフェースを実装する必要があります。
3.xでの典型的なハンドラの例を見てみましょう。それは、現在の選択に基いて何かを行います。この例では、ハンドラは現在の選択がMailAccount型かどうかチェックします。もし、その結果が真なら、ユーザがログイン済みかチェックし、メールを送受信します。
|
この設計には3つの主要な問題があります。定型的なコード記述、テスト容易性の不足、再利用性の不足
です。
このハンドラに対して、テストケースを書いた場合を想像してみましょう。あなたは、手でExecutionEventを生成し、さらにHandlerUtilがテスト環境で利用可能かどうかを確かめる必要があります。この場合の選択は、単純なフィールドでなく、プロパティであることから、
モックのExecutionEventを適切に準備する方法を理解するために、
HandlerUtil.getCurrentSelection()の実装を見なくてはならないでしょう。
最後のセクションでは、さらに定型的なテストコードをテストコード内に持つことになります。もし、テストケースの作成をあなたが管理することになったとした場合、
タイマーに基いたメールの同期を引き起こしたい、要するに、
その実行メソッドを直接呼び出したいと考えることを想像してみましょう。
そのハンドラを再利用するためには、ExecutionEventを生成する必要があるはずです。もし、ハンドラがあなたの制御下にあるなら、たぶん、この時点でリファクタリングするでしょう。
しかし、ハンドラはリファクタリング不可能なフレームワークの中にあるかもしれません。
これに対する解決策は、とてもシンプルで、コードを2つのメソッドに分離することです。最初のメソッドは、ワークベンチに特化した部分、すなわち、選択をアンパックするところ
を扱います。2番目のメソッドは、ビジネスロジックを実行するためのもので、このケースではスタティックメソッドにできます。
|
この設計で、2番目のメソッドに対するテストケースは書きやすくなります。加えて、そのメソッドは、他のどの場所からも簡単に呼び出されることができます。
例えばタイマーベースの同期をトリガすることが挙げられます。最後に、コードが理解しやすくなります。
次のステップですが、2番目のメソッドをハンドラから外に、例えばワークベンチ依存がない
プラグインに移動することができます。
これと同じデザインパターンをビューに適用し、同様の利点を得ることができます。
我々は一つのワークベンチに特化したクラスと、一つのPOJOになれるクラスを持っていることになります。
次の例では、WorkbenchViewは、現在の選択を扱うことも含めて、すべてのワークベンチ
特化部分を担います。その一方でPOJOViewは完全に独立しています。
|
繰り返しになりますが、今やPOJOViewは、とても理解しやすく、テストしやすく、そして
再利用しやすい状態です。例のようにPOJOViewは、JFaceウィザードに組み込もうと思えば可能です。ここまでで、Eclipse4特有の概念は何も使っていません。これまで出てきた設計パターンは、
ただの3.xで使うことができます。
(3.xのインタフェースを実装するための)ラッパークラスは、たいていこれと良く似ているので、
いくつかの一般的な実装を準備することは容易でしょう。次のセクションでは、そのような依存性注入を使う一般的な実装を紹介します。
3.xにおける依存性注入
ワークベンチ依存のコードと、POJOのようなカスタムコンポーネントを分離すると、 3.xでさえ、コンポーネントの再利用とテストが容易になります。しかし、Eclipse4アプリケーションプラットフォーム向けのコンポーネント開発と比較すると、 2つの不利な点があります。
1. ラッパーは手で実装し、拡張ポイントを等して登録しなければなりません
2. コンポーネントの実装に依存性注入を使うことができないので、Eclipse4でそのまま使えません。
ひとたび、あなたのアプリケーションがEclipse 4.x版で動けば、まだ3.xのAPIを使っているとしても
この問題への解決策はあります。
その解決策とは、トムシンディによって開発が進められているe4ツールプロジェクトから
提供される 3.x e4ブリッジです。このプラグインは、基本的にジェネリックばラッパークラスを提供し、
それは、3.xアプリケーションで使うことができます。
そのラッパークラスは、POJOである第2のクラスを定義することを可能とし、対応する
コンポーネントを実装します。この解決策は、以前述べたのと同様のパターンに従いますが、一般的な方法で動作し、
依存性注入をサポートします。執筆時点では、ビューとエディターの実装が利用できます。3.x のワークベンチラッパーを生成するためには、それぞれの型、例えば、
Viewを実装するDIViewPartなどから単純に派生させます。
このラッパークラスはほとんど空です。やらなければならないことは、コンポーネントを実装するPOJOを指定することです。
|
このクラスは、3.xでやっていたようにViewの拡張ポイントを使って登録されます。
ビュー自身の実装は、POJOにすることができ、それゆえ依存性注入が利用できます。今々のプログラミングの利便性に加えて、コンポーネントがe4に移行される場合に
何らかの編集なしに使うことができます。
このケースでは、ラッパーと拡張記述を取り除き、POJOViewをアプリケーションモデルに統合する
ことができます。見ればわかるように、ビューは、現在の選択への注入も含む依存性注入のすべての
機能を使うことができます。
|
これがどうやって動作しているかを理解するために、もっともシンプルなケースである、
ハンドラ―に対するラッパー(私が最近コントリビュートしました)を見てみましょう。
例を単純にするために、今は@CanEnableアノテーションを無視しましょう。DIHandlerは、3.xでやっていたように、ハンドラ―拡張ポイントで登録できるように、
3.x IHandlerインタフェースを実装する必要があります。加えて、DIHandlerは、ラップしているPOJOクラスについて知る必要があります。このPOJOクラスは、ラッパーによって初期化されます。これを行うには、e4 ContextInjectionFactoryを使用します。アプリケーションは、互換性レイヤで動作しているので、EclipseContextをサービスとして
読み出すことができ、クラスを生成するために使うことができます。
このようにハンドラによって期待されるすべてのフィールドは、注入されます。
(e4で標準的にやっているように)
|
唯一今欠けているものは、実行メソッドの実装です。再度、@Executeを付けたPOJOのメソッドを呼び出すために、単純にInjectionFactoryを使用します。
|
このDIHandlerは、それほど複雑なものではなく、POJOなハンドラーを3.xワークベンチにラップする ことができます。
まとめ
このチュートリアルは、3.x から Eclipse4プログラミングモデルへのソフトな移行に対する
アプローチを述べました。
カスタムUIコンポーネントとワークベンチ依存クラスの実装を分離する概念の説明から始めました。これは、コンポーネントの再利用性とテスト容易性を改善します。ブリッジプラグインを使うと、e4ツールラッパークラスを手動で実装する必要が無くなります。加えて、DIWrapperを使うと、3.xでのプログラミング時にも依存性注入が使えるようになります。
このような方法で開発されたコンポーネントは、何らかの適合処理を加えることなく、純粋な
e4アプリケーションに統合することが可能となります。