BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル タグからリッチへ: Web 1.0からFlexへ

タグからリッチへ: Web 1.0からFlexへ

ブックマーク

はじめに

iPhone の成功によって明確に示されたのは、より対話的(インタラクティブ)なソフトウェア体験をユーザたちは望んでいる、と言うことでした。対話的であればあるほど、アプリケーションが持つ機能を効率的に利用し、より高い効果を挙げることができます。そしてそれが(個人的な情報管理だけではなく)エンタープライズな業務アプリケーションにとっても、対話性が非常に重要である理由です。業務アプリケーションにおける「よりよい対話性」とは、ほとんど「データの視覚化」を表します。なぜなら、業務においてより効果的・効率的であるということは、よりよい意志決定や、利益が即座にもたらされることと同義だからです。ダッシュボードはデータを視覚化するアプリケーションの典型的な例です。興味深いことに、今日における多くのダッシュボードは、効果的なユーザ体験を作り出すための対話性に欠けています。そこで我々は、典型的なWeb 1.0のダッシュボードを、より対話的でリッチなダッシュボードに改良することにしました。私たちは、車輪の再生産を行ったり、アプリケーション全体を一から作成するわけではありません。代わりに我々はインターフェースを再作成し、既存のサーバサイドインフラにそれを組み込みました。そうすることにより、私たちは素早く、しかし実用的な(Web 2.0アプリへの)変換を実現したのです。

今回のエクササイズで私たちが使用するダッシュボードは、オープンソースで提供されているPentaho BIスイートの一部です。データとビューは、ディストリビューションに含まれているサンプルアプリケーションの一部です。

私たちが使うサンプルはダッシュボードですが、そのコンセプトは、Web 1.0からRIAへの移行を必要とする全てのプロジェクトに適合します。私たちは、RIAのツールキットとしてAdobe Flexを選びました。私たちが今回論じているのは全てFlexフレームワーク、Flash VM、サポートされているライブラリについてです。

これ以降の記事を読み進めるには、以下のソフトウェアをインストールする必要があります。

Flex インターフェースを動かす前に、Pentahoサーバを起動して、ダッシュボードにログインするのを忘れないでください。(この記事でお見せする) Flexインターフェースは、あなたがすでにログインして認証を受けていると仮定しています。ソースコードは、サーバがHTTPリクエストをポート 8080で受け付けると仮定しています。もしあなたのPentaho HTTPサーバが、他のポートでリクエストを待ち受けているなら、ソースコードを適切に修正してください。またFlexインターフェースに表示されるダミーデータは、Pentahoサーバを同時にインストールするのをスキップしたい、と言う人の利便性を考えて、ソースコードのダウンロードアーカイブに含まれています。

セットアップが終わったら、サンプルアプリケーションに取りかかりましょう。

自分のPentahoダッシュボード

先にお断りしておくと - この記事は、"事始め"として書かれました。必須というわけではありませんが、もしあなたがFlexの経験を以前からお持ちなら、learn.adobe.com(英語)かflex.org(英語)を見てみた方が良いかもしれません。この記事では、保守しやすいコードを書くためのアーキテクチャや、ユーザインターフェースデザインのベストプラクティスをお伝えしようとはしていません。例えば、この例ではEly Greenfieldの、チャートをドリルダウンさせるコンポーネント(source) [デモ](source)を使わないことにしました。なぜなら、それはユーザエクスペリエンスを向上させますが、サンプルを動かすのに若干追加の作業が必要とされてしまうからです。私たちは、このコードを試してみたい方に対して「単純にコピーアンドペーストすれば良い」と言う体験を提供したいのです。サードパーティのコンポーネントを追加したり、真のMVCアーキテクチャーを採用したりすることは、こうした体験を複雑にしてします。もしあなたがそうしたトピックを徹底的に調べることに興味があるなら、数多くの記事をWeb上やAdobe Developer Connection(サイト・英語)上で見つけることができるでしょう。

まずは最終的な結果を見てみてください。そうすれば、私たちが作り出そうとしている体験を理解することができるでしょう。デモはこちら(source)

オリジナルのPentahoダッシュボードも、見た目は似ています。

前述のように、私たちは新しいダッシュボードを作るためにAdobe Flexを使いました。Flexペースのダッシュボードは、宣言的なMXML言語と手続き型のActionScriptでコードが書かれており、フリーの Flex SDKによってSWFへとコンパイルされています。SWFファイルはFlash Player VM向けのバイトコードです。あなたはSWFファイルをブラウザ内で動かしたり、新しく登場したAdobe Integrated Runtime (AIR) によってデスクトップアプリケーションとして動かすこともできます。新しいダッシュボードを作るためのソースコードを見てみてください。

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()" layout="horizontal">
<mx:Script>
<![CDATA[

// ActionScriptで使われ、MXMLでは使用されないクラスをインポートします。
// フリーのFlex SDKに含まれるmxmlcコンパイラにより、ActionScriptコードはMXMLから生成されます。
// mxmlcに-compiler.keep-generated-actionscriptと言う引数を渡せば、生成されたActionScriptを見ることができます。
import mx.charts.HitData;
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;

// Bindableはメタデータ/アノテーションです。イベントコードを生成して、
// 変数をMXMLのバインディング式内部で使用できる(例: dataProvider="{territoryRevenue}")ようにします。
[Bindable] public var territoryRevenue:ArrayCollection;
[Bindable] public var productlineRevenue:Object;
[Bindable] public var topTenCustomersRevenue:Object;

// ActionScript内の変数は、Javaのような名前空間を持ちます。典型的なpublic、private、
// protected、そして自作した名前空間も同様に用いることができます。
// コロン文字とともにオブジェクトの型を指定できます。省略可能ですが、指定することが推奨されています。
private var _selectedTerritory:String = "*";
private var _selectedProductLine:String = "*";

// initApp関数は、アプリケーションのcreationCompleteイベントが発生したときに呼び出されます(上のmx:Applicationタグを見てください)
private function initApp():void
{
// データのキャッシュを初期化します
productlineRevenue = new Object();
topTenCustomersRevenue = new Object();

// 地域データから売上高を取得するための、サーバリクエストを初期化します。
// tSrvは以下のMXMLで定義されています。ActionScript内で定義することも可能ですが、tSrv.send()と言うように少し冗長になります。

// 製品ライン売り上げとトップ10顧客売り上げが、選択された地域に依存しているため、
// 選択された地域に基づいたデータを読み込む(もしくはキャッシュから取り出す)ための関数呼び出しを行います。
// この場合選択された地域は、"*"か、もしくは私たちが指示したものです。ユーザが新しい地域を選択したとき、
// 選択された地域が異なっていれば、これらのメソッドは再度呼び出されます。
updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

// このsetterメソッドは製品ライン売り上げとトップ10顧客売り上げのデータを更新し、それに応じてチャートも更新します
public function set selectedTerritory(territory:String):void
{
// プライベートな、バッキング変数を更新する
_selectedTerritory = territory;

updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

// 選択されている地域を返すgetterメソッド。
// このメソッドはselectedTerritoryプロパティをバインディング式で使用できるよう、
// Bindableメタデータ/アノテーションを持ちます。
[Bindable] public function get selectedTerritory():String
{
return _selectedTerritory;
}

// selectedTerritoryと同様のsetterメソッドですが、選択された製品ラインのためのものです。
public function set selectedProductLine(productLine:String):void
{
_selectedProductLine = productLine;

updateTopTenCustomersRevenue();
}

[Bindable] public function get selectedProductLine():String
{
return _selectedProductLine;
}

// データがキャッシュされていれば、選択された地域に基づくチャートを直接更新する
// データがキャッシュに無ければ、Webサービスのリクエストに必要とされる「名前:値」のペアを組み立て、
// その後リクエストを生成する
private function updateProductLineRevenue():void
{
if (productlineRevenue[_selectedTerritory] == undefined)
{
productlineRevenue[_selectedTerritory] = new ArrayCollection();

var p:Object = new Object();

if (_selectedTerritory != "*")
{
p.territory = _selectedTerritory;
}

plSrv.send(p);
}
else
{
plPie.dataProvider = productlineRevenue[_selectedTerritory];
}
}

// updateProductLineRevenueと同様ですが、選択された地域と生産ラインの両方がデータセットを決定します
private function updateTopTenCustomersRevenue():void
{
if (topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine] == undefined)
{
topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine] = new ArrayCollection();

var p:Object = new Object();

if (_selectedTerritory != "*")
{
p.territory = _selectedTerritory;
}

if (_selectedProductLine != "*")
{
p.productline = _selectedProductLine;
}

ttcSrv.send(p);
}
else
{
ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine];
}
}

// この関数は、地域売り上げを取得するためのサーバからのレスポンスを処理します。データを、チャートが期待する形式へと
// 再編成します。tPieチャートは、元になるArrayCollectionに対して、for eachループ内で行われる変更に反応します。
// 変更があったことを見つけると、データのビューを更新します。
private function handleTResult(event:ResultEvent):void
{
territoryRevenue = new ArrayCollection();
tPie.dataProvider = territoryRevenue;

var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-HDR-ROW']['COLUMN-HDR-ITEM'];
for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl['DATA-ITEM'][1];
territoryRevenue.addItem(spl);
}
}

// handleTResultと同様ですが、製品ライン売り上げのデータを処理します。
private function handlePLResult(event:ResultEvent):void
{
var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-HDR-ROW']['COLUMN-HDR-ITEM'];

for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl['DATA-ITEM'][1];
productlineRevenue[_selectedTerritory].addItem(spl);
}

plPie.dataProvider = productlineRevenue[_selectedTerritory];
}

// handelTResultと同様ですが、トップ10顧客売り上げのデータを処理します。
private function handleTTCResult(event:ResultEvent):void
{
var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['ROW-HDR-ROW'];
var pl:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'];

for (var i:int = 0; i < pl.length; i++)
{
var spl:Object = new Object();
spl.name = hdr[i]['ROW-HDR-ITEM'][0];
spl.sales = pl[i]['DATA-ITEM'];
topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine].addItemAt(spl,0);
}

ttcBar.dataProvider = topTenCustomersRevenue[_selectedTerritory + '_' + _selectedProductLine];
}

// この館数は、tPieチャートにおけるデータツールチップをフォーマットするために呼び出されます。
private function formatTPieDataTip(hitdata:HitData):String
{
return "<b>" + hitdata.item.TERRITORY + "</b><br>" + cf.format(hitdata.item.SOLD_PRICE);
}
]]>
</mx:Script>

<!-- これらのHTTP Servicesは、HTTPを通じてサーバと会話します -->
<mx:HTTPService id="tSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel-wheels/homeDashboard&action=Sales_by_Territory.xaction" result="handleTResult(event)"/>
<mx:HTTPService id="plSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel-wheels/homeDashboard&action=Sales_by_Productline.xaction" result="handlePLResult(event)"/>
<mx:HTTPService id="ttcSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=samples&path=steel-wheels/homeDashboard&action=topnmdxquery.xaction" result="handleTTCResult(event)"/>
<!-- 通貨のフォーマットを正しく行うための、不可視のコンポーネントです。formatTPieDataTip関数で使用されます -->
<mx:CurrencyFormatter id="cf" precision="0"/>

<!-- チャートをよりインタラクティブにするために使用されるエフェクトです -->
<mx:SeriesInterpolate id="plEffect"/>
<mx:SeriesSlide id="ttcSlide" direction="right"/>

<!-- スタック形式の、縦方向にレイアウトするコンテナ -->
<mx:VBox height="100%" width="40%">
<!-- 省略可能な影付き、タイトルバー、コントロールバーを備えたナイスなボックス -->
<mx:Panel width="100%" height="100%" title="Revenue By Territory">
<!-- 円グラフ -->
<mx:PieChart id="tPie" width="100%" height="100%" showDataTips="true" dataTipFunction="formatTPieDataTip">
<!-- ActionScriptコードを埋め込むため、円グラフのitemClickプロパティをセットします。上で定義された関数を呼び出すこともできます -->
<mx:itemClick>
// 適切なsetterメソッドを呼び出す
selectedTerritory = event.hitData.item.TERRITORY;

// ユーザにクリックされた、円グラフの一部分を展開するよう、円グラフに伝える
var explodeData:Array = [];
explodeData[territoryRevenue.getItemIndex(event.hitData.item)] = 0.15;
tPie.series[0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>
<!-- 円グラフのseriesプロパティにセット -->
<mx:series>
<!-- Pie Seriesは、円グラフが自身のデータをどう表示すればよいかを定義します -->
<mx:PieSeries nameField="TERRITORY" field="SOLD_PRICE" labelPosition="insideWithCallout" labelField="TERRITORY"/>
</mx:series>
</mx:PieChart>
</mx:Panel>

<!-- パネルにおけるタイトルバー内のBinding式は、BindableとマークされているselectedTerritoryプロパティのgetterを使用します -->
<mx:Panel width="100%" height="100%" title="Revenue By Product Line (Territory = {selectedTerritory})">
<mx:PieChart id="plPie" width="100%" height="100%" showDataTips="true">
<mx:itemClick>
selectedProductLine = event.hitData.item.PRODUCTLINE;

var explodeData:Array = [];
explodeData[productlineRevenue[_selectedTerritory].getItemIndex(event.hitData.item)] = 0.15;
plPie.series[0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>
<mx:series>
<!-- シリーズにおけるshowDataEffectは、上で定義されたエフェクトを(再)利用するためBindingを使用しています -->
<mx:PieSeries nameField="PRODUCTLINE" field="REVENUE" labelPosition="insideWithCallout" showDataEffect="{plEffect}" labelField="PRODUCTLINE"/>
</mx:series>
</mx:PieChart>
</mx:Panel>
</mx:VBox>
<mx:Panel width="100%" height="100%" title="Top 10 Customers (Territory = {selectedTerritory} | Product Line = {selectedProductLine})">
<mx:BarChart id="ttcBar" width="100%" height="100%" showDataTips="true">
<mx:series>
<mx:BarSeries xField="sales" showDataEffect="{ttcSlide}"/>
</mx:series>
<mx:verticalAxis>
<mx:CategoryAxis categoryField="name"/>
</mx:verticalAxis>
</mx:BarChart>
</mx:Panel>

</mx:Application>

ソースコードを読むか、もしくはダウンロードしてください(source) 。 アプリケーションには二つのバージョンが存在することに注意してください。pentaho_dashboard_demo.mxmlは、偽のデータセットを使用しています。pentaho_dashboard.mxmlは、実際のPentahoサーバに接続してデータを取得します。

移植プロセス

RIA への移植を行うプロセスは、新しいインターフェースをデザインするところから始まります。同時に、あなたのアプリケーションがRIAに向けて、データとサービスをどのように公開するかを計画しておく必要があるでしょう。Pentahoでは、データとサービスはすでに我々に対して公開されていました。そのためもっとも難しかったのは、データを解析してFlexのチャートコンポーネントが期待するフォーマットに変換する部分でした。ある時点で、新しいインターフェースからバックエンドのサービスを呼び出すことができます。こうしたステップをさらに詳しく見ていきましょう。

新しいインターフェースをデザインする

新しくRIAインターフェースを作成するためのもっとも良い方法は、既存のインターフェースをよりリッチにする方法を考えることではありません。ユーザがどのように情報を視覚化し、対話したがっているかを考え直すことです。この過程において、デザイナが非常に役立ちます。可能であれば、彼らの創作意欲を最大限発揮させてください。あなたは開発者として、プロトタイプを作り始めることができます。これを効果的に行うためには、モックのデータセットを作る必要があるかもしれません。我々が使用したデータセットは、Sales_by_Productline.xactionや Sales_by_Territory.xaction、topnmdxquery.xactionと言ったファイルにあります。今回作成したモックのデータセットは、Pentahoが公開しているWebサービスそっくりに見えるものです。必ずしもこうしておかねばならないと言うわけではありませんが、好みのデザインが決定したときに、リアルなサービスに置き換えるのが簡単になります。モックのデータセットを用いることにより、デザインにおいて、よりスピーディなイテレーションを行うことができます。

実際に作成したデザインは、オリジナルのダッシュボードとほとんどまったく同じに見えます。もしデザイナが我々を助けてくれたなら -- そうしなかったのですが -- 何かしら、よりクリエイティブなデザインにすることができたでしょう。しかし、我々は開発者ではありますが、もっと対話的なダッシュボードを作成することも可能でした。私たちはよりリッチなインターフェースを相当数作ってきましたが、この例では、コードを読みやすく、理解しやすく保っておきたかったのです。

UIを作成するためのコードは、かなり単純です。円グラフを作成するには、以下のようなMXMLを単純に追加するだけです。

<mx:PieChart width="100%" height="100%">
<mx:series>
<mx:PieSeries nameField="TERRITORY" field="SOLD_PRICE" labelPosition="insideWithCallout" labelField="TERRITORY"/>
</mx:series>
</mx:PieChart>

対話性を追加するため、itemClickイベントハンドラを円グラフに追加することができます。

<mx:itemClick>
selectedTerritory = event.hitData.item.TERRITORY;

var explodeData:Array = [];
explodeData[territoryRevenue.getItemIndex(event.hitData.item)] = 0.15;
tPie.series[0].perWedgeExplodeRadius = explodeData;
</mx:itemClick>

Flex はプロパティをサポートしているため、あなたがselectedTerritoryをセットしたときに、itemClickイベントハンドラで行っていたような何らかの処理を行うことができます。この場合では、円グラフの一部が紐づけられているデータセットのリフレッシュを行いました。

public function set selectedTerritory(territory:String):void
{
_selectedTerritory = territory;

updateProductLineRevenue();
updateTopTenCustomersRevenue();
}

また、データセットが変更されたら、スムーズにチャートを変更するようにするのも非常に簡単です。最初に行うのは、使いたいエフェクトのインスタンスを一つ追加することです。

<mx:SeriesInterpolate id="plEffect"/>

それから、データが変更されたときこのエフェクトを使用するよう、円グラフに対して伝えることができます。私たちは、使いたいエフェクトのインスタンスをshowDataEffectに紐づけました。

<mx:PieSeries nameField="PRODUCTLINE" field="REVENUE" labelPosition="insideWithCallout" showDataEffect="{plEffect}" labelField="PRODUCTLINE"/>

また、マウスオーバー時にカスタムのデータチップを追加することもできます。

<mx:PieChart id="tPie" width="100%" height="100%" showDataTips="true" dataTipFunction="formatTPieDataTip">

dataTipFunctionで指定されたメソッドformatTPieDataTipは、データチップ内で使用されるカスタム文字列を返します。

private function formatTPieDataTip(hitdata:HitData):String
{
return "<b>" + hitdata.item.TERRITORY + "<b><br>" + cf.format(hitdata.item.SOLD_PRICE);
}

このほかにも、アプリケーションのルック・アンド・フィールをカスタマイズするために、スタイルをたくさん指定することができます。こうしたスタイルは、プロパティとしてインラインで指定することもできますし、外部のCSSファイルで指定することもできます。

バックエンドを公開する

Pentahoでは、ダッシュボードに必要なデータを公開しているWebサービスを見つけ、対話するのは簡単です。地域ごとの売上高を返すURLはこちら(source)です(ローカルで動かしていた場合)。

どのデータセットを返すか、を指定するためのパラメータをとるURLもあります。例えば、トップ10顧客を返すWebサービスは、二つの省略可能なパラメータをとります - それは地域と生産ラインで、情報のサブセットをどのように返すかを決めるものです。

フロントとバックをつなぐには

フロントエンドをバックエンドにつなぐため、まずはHTTPService (SOAPを使っている場合はWebService) を作成するところから始めます。)。

<mx:HTTPService id="tSrv" url="http://localhost:8080/pentaho/ServiceAction?solution=
samples&path=steel-wheels/homeDashboard&action=Sales_by_Territory.xaction"
result="handleTResult(event)"/>

result プロパティは、サーバからのレスポンスが返ってきたときに実行するコードを指定します。この場合、handleTResultと言う名の関数にイベント引数を一つ渡して呼び出すだけです。その関数は、我々が受け取ったデータを、チャートが必要とする形式に変換する責務を持ちます。チャートだけではなく DataGridのようなその他のコンポーネントを使う場合でも、こうした調整は何かしら必要になるでしょう。この場合、チャートにデータを渡す前に、いくつかの小さな処理を行います。

private function handleTResult(event:ResultEvent):void
{
territoryRevenue = new ArrayCollection();
tPie.dataProvider = territoryRevenue;

var hdr:ArrayCollection = event.result.Envelope.Body.ExecuteActivityResponse.swresult['COLUMN-HDR-ROW']['COLUMN-HDR-ITEM'];

for each (var pl:Object in event.result.Envelope.Body.ExecuteActivityResponse.swresult['DATA-ROW'])
{
var spl:Object = new Object();
spl[hdr[0]] = pl['DATA-ITEM'][0];
spl[hdr[1]] = pl['DATA-ITEM'][1];\\\\\\\\
territoryRevenue.addItem(spl);
}
}

この例では、全てのコードが単一のファイルに書かれています。現実世界のアプリケーションでは恐らく、モデル・ビュー・コントローラアーキテクチャに従って異なるファイルに分割するでしょう。いくつかの実績あるデザインパターンを用いて大きなアプリケーションを構築する、と言うトピックについてはまた別の機会に議論したいと思います。今のところは、サンプルが示しているところまで行うとしましょう。ここから記事の終わりまでにかけては、Adobe Flexを用いたRIAの興味深い側面をいくつか論じ、このサンプルアプリを商用品質のソリューションにするために何ができるか、を示唆しています。

このサンプルの何がすごいのか?

このサンプルは、伝統的な古いスタイルのWebアプリケーションを、よりリッチでより対話的なユーザインターフェースにすることの重要性を手早くデモしたものです。このアプリの美しいところは、大規模なリファクタリングを必要とすることなく、既存のアプリケーションに対して素晴らしいインターフェースを提供したことです。これほど手軽に移植を行えたことの理由は、Pentahoが自身のサーバサイド呼び出しをWebサービスのエンドポイントとして公開されていることと、そして、Flexが自身のコンポーネントモデルとバインディングモデルの中で、これらのサービスをエレガントに扱えることに起因しています。

またこのサンプルは、テクノロジーを用心深くミックスして適用することをデモしています。質が良く堅牢なJavaサーバアプリケーションは、リッチな Flexインターフェースと効果的に組み合わせて、説得力のあるアプリケーションを作成することができます。これは素晴らしく価値のある事柄であり、このサンプルはその恩恵にあずかっています。

このアプリケーションの他の側面としては、「ActionScriptとMXMLを使ってFlex アプリケーションを作るのがいかに簡単か」を、実際に動作するコードを通して表していると言うことです。JavaとXMLに慣れ親しんだ人々にとっては、そのシンタックスとセマンティクスはとても親しみやすいですね!

何が欠けていますか?そして、その溝をどうしたら埋められますか?

このサンプルは製品レベルのコードだとは言えません。単純なプロトタイプであることを主眼においています。しかし、PentahoのWebサービス呼び出しをActionScriptのライブラリに抽象化する、と言う小さな努力は、堅牢なアプリケーションを構築するための良き第一歩だと言えるでしょう。そうしたライブラリを構築するための努力がオープンソースによって進行中です。この例でとっているアプローチは手続き型で、オブジェクト指向の概念もほんの少ししか使用していません。モデル・ビュー・コントローラアーキテクチャパターンの使用、インターフェースに対するプログラミング、継承とポリモフィズムの適切な使用により、保守が容易でクリーンなアプリケーションを作ることができます。また今回のサンプルでは、アプリケーションのルックアンドフィールは(元になったWeb 1.0アプリから)コピーしました。理想的には、対話に関する要件に基づいて完全に新しいインターフェースを作成してから、ヴィジュアルなコンポーネントをWebサービスコンポーネントに紐付けるべきです。製品レベルのアプリケーションを作成するためには、そうした努力に時間とエネルギーを費やす必要があります。

さらに知りたい方は

このサンプルは、RIAで行えることのほんの一部です。私たちにできる改善の一つとしては、ドリルダウン可能なチャートへの移行です。Ely Greenfieldは説明付きのデモとコードを作成することで、Flexチャートを使ったドリルダウンをいかにして実装するかを示しました。その詳細とデモに関しては彼のブログ(source)を見てください。私たちは、このデモを作るのにFlex 2を使いましたが、Flex 3のチャートコンポーネントには、ほんのわずかですが新しい機能があります。そうした機能についてはここ(source)とここ(source)で読むことができます。もしFlexプログラミングについてさらに学びたいのであれば、flex.org(英語)とlearn.adobe.comand(英語)をチェックしてください。

著者について

James WardはAdobeに所属している、Flex向けのテクニカルエバンジェリストです。また、JSR 286、299、301に対するAdobeのJCP代表者でもあります。彼は登山を愛し、それと同様にプログラミングを楽しんでいます。なぜならそれは終わることのない新しい発見、エレガントな解決策、頂上もあれば谷もあるからです。登山においては、彼は様々な場所で冒険を繰り広げてきました。同様に、テクノロジーは彼を多くの冒険に導いています。以下に示すのは、彼のそうした冒険の数々です: 90年代の初めにはPascalとアセンブリ、90年代半ばにはPerl・HTML・JavaScript、そして90年代末にはJavaとそのフレームワークの多くが始まったのです。今日、彼は美しいフロントエンドを構築するためにFlexを主に用い、Javaをバックエンドに使っています。Adobe に入る前は、JamesはPillar Data Systems向けのリッチな市場/顧客サービスのポータルを作っていました。Jamesについては、彼のブログ(www.jamesward.org(英語)でより多くを知ることができます。: .

Shashank Tiwariは、Saven Technologies社(サイト・英語)のチーフテクノロジストです。同社はシカゴを基盤としており、銀行や金融サービス企業向けの、最先端テクノロジーからなるビジネスソリューションを提供しています。Shashankは多作な開発者・著者・講演者で、JCPではJSR 274, 283, 299, 301, 312についてのエキスパートグループのメンバーとして活動中です。彼はJava、ActionScript、Python、Perl、PHP、C++、 Groovy、JavaScript、Ruby、Matlabを含む少なくとも1ダース以上の言語でプログラムを行っています。彼はO'reillyネットワークにおいても人気のあるブロガー(source)です。今日、彼はFlexとJavaを用いたWeb 2.0アプリケーションの構築にいそしんでいます。彼についてさらに知りたければ、http://www.shanky.orgt/ (英語)から得ることができます。

原文はこちらです:http://www.infoq.com/articles/web-flex-port

この記事に星をつける

おすすめ度
スタイル

BT