本記事は2003年に執筆されたものです。Struts全般の最新情報は@IT Java Solutuionのカテゴリ「Webアプリケーション(Struts、WTP、JSFなど)」をご参照ください。
昨今、とみに「フレームワーク・プログラミング」という言葉が取りざたされることが多くなってきました。そして、本稿のテーマでもあるStrutsもまた、「サーバサイドJava」――サーブレットベースで動作する「アプリケーション・フレームワーク」の一種です。
Strutsプログラミングの具体的な手続きを紹介していくに先立って、まずはこのアプリケーション・フレームワークとしてのStrutsについて、簡単に解説しておくことにしましょう。
フレームワーク、それはアプリケーションを構築するうえでの「枠組み」であり、「ルール」であり、(語弊を恐れずにいえば)「制限」です。
昨今、アプリケーション構築におけるチーム開発の重要性がますますクローズアップされています。アプリケーションがますます大規模化し、また、基幹システムの一角をも担うようになってきた今日、もはやWeb アプリケーションが単なる一開発者の片手間仕事ではあり得なくなってきたということです。要件の複雑さが増してくるのとは反比例的に、開発納期は短くなっています。その中で、効率よく、かつ堅牢なシステムを構築するには、さまざまなスキルを持った多くの人間の力が必要となってきています。画面(UI)を設計するデザイナー、アプリケーションロジックを組み立てるプログラマ、あるいはコンテンツを作成する編集者……さまざまな人間による協業は、もはやアプリケーション開発にとって必須の要件であるといえるでしょう。
ところが、その開発に携わる1人1人がそれぞれ勝手に、アプリケーションの個別の部品を作り始めたとしたらどうでしょう。それぞれの部品は確かに高品質なものができた、しかし、いざお互いを組み合わせようとしたら、どうにもこうにもつながらない、動かないというのは決して笑い話ではないのです。多くの人間が1つのシステムにかかわれば、それだけ誤解もあれば、間違いも意識の相違もあります。完ぺきな取り決めをしたつもりでも、それが個々人によってまったく違う受け止め方をされていたというのは、決して珍しい話ではありません(これは、たとえきちんとした開発標準化のドキュメントを作成していたとしても防げるものではありません)。
そこで登場するのがアプリケーション・フレームワークなのです。アプリケーション・フレームワークは、どんなアプリケーションにも必要になるデータの入出力やエラー処理、画面遷移などの基本的なしくみを提供します。これは、いつも同じようなロジックを記述する必要がなくなるという、「開発生産性」の観点からのみのメリットではありません。フレームワークを用いることで(フレームワークに従うことで)、同じ目的で書いたロジックならば「誰が書いても」均質なコードを保証できるのです。
これはチーム開発においては重要なことです。実態と乖離(かいり)しがちな(そのため、実効力が低いことが多い)標準化ドキュメントを工数をかけてメンテナンスする必要もありません。チーム同士でモジュール(部品)間のインターフェイスを確認しあう必要もありません。最終的にどのようにモジュールを結合しようか設計する必要すらないのです。われわれにとって必要なことはただ「フレームワークが提供するルール」に従う――それだけです。
もっとも、このことは半面として「フレームワークは人間に制限を課す」といわれるゆえんでもありますが、これはフレームワークが標準化のルールを強制することとの裏表ともいえましょう(標準化ドキュメントと異なり、フレームワークはルールを破った人間に対して、「エラー」という形で警告を発します)。「このフレームワークはわれわれの開発体制に合わない」と批判するのは簡単ですが、フレームワークが提供するルールにシステムを合わせていくのも、これからのSEの仕事なのではないかと筆者は思います。
さて、Strutsはあまたあるアプリケーション・フレームワークの中でも「MVCシステムデザイン」をベースに設計されたフレームワークです。Struts自体の機能を知る前に、まずはより汎用的な概念として、このMVCシステムデザインについて紹介しておきましょう。
「MVCデザインパターン」は、アプリケーションを大きく以下の3つのレイヤ(層)に分割します。
要素 | 概要 | |
---|---|---|
M(Model) | ロジックの中核やデータベースアクセスなどをつかさどり、画面レイアウトなどの、表層的なレイヤの影響を最も受けにくいレイヤ | |
V(View) | ユーザーインターフェイス(プレゼンテーション層)。入力フォームや処理結果の出力などをつかさどり、最も変動要素の大きいレイヤ | |
C(Control) | Viewからの入力データをModelに振り分け、Modelでの処理結果を再び適切なViewに割り当てる結節部。画面遷移やView・Modelのマッピングを制御する、アプリケーションのエンジンともいうべきレイヤ | |
MVCを図示すると以下のようになります。
MVCシステムデザインでは、このようにアプリケーションを役割単位に分割することで、デザイナーやプログラマ(またデータベース設計者や編集者)など、アプリケーション開発に携わる人々の分業(並行作業)を可能にします。画面上の「注文年月日」をスクリーンの下部から上部に表示されるよう変更したからといって、いちいちプログラマのあなたが出張っていく必要はないのです。それぞれの分担の人間がそれぞれの机で自分の仕事に集中できる、これはチーム開発において極めて重要なことでしょう。
さて、ここまでアプリケーション・フレームワーク導入の利点ばかりを紹介してきました。フレームワークを利用することで「開発生産性が向上する」「適切な協業・分業体制で開発を進められる」「後々のメンテナンスが容易になる」などなど、うたい文句を聞いている限りはなにやらいいことづくしのパラダイムのように聞こえます。
しかし、それでは、既存の「サーバサイドJava」アプリケーションを、なんでもかんでもStrutsに置き換えてしまうのが好ましいのでしょうか。これははっきりと「否」です。
Strutsに限らず、多くのフレームワークは、生産性・保守性向上の手段としてアプリケーションを機能単位に分割するのが基本です。しかし、ファイルを分割するとアプリケーション全体の構成が見えにくくなるのも事実です。人間にとって最も理解しやすく、誤解も招かないコードの記述方法とは、旧来の手続き型の記法にほかならないのです。
しかし、それをあえて機能単位に分割するというのは、もはやシステムが従来のように「作って、はい終わり」の代物ではなくなってきているからです。その時々のビジネス要件によって流動的に変更されるのが当たり前の昨今システムでは、いかに変更の影響個所を限定するかもまた、重要な要件の1つであるといえましょう。
これは半面で、要件が固定的でもあり、将来的にさほど手を入れる可能性がない、あるいは、変更するくらいならば作り直した方が早い小規模なアプリケーションにおいて、フレームワークを活用する意味合いはさほどにないということです。JSPやサーブレットの仕様のみならず、フレームワークのしくみを学習することは、やはり開発者にとって少なからぬ「負荷」であり、足かせでもあります。フレームワークのメリットが得られないならば、ただでさえも忙しい開発者にこうした余計な負荷を課すべきではないでしょう。
フレームワークは、これまでのすべてのアーキテクチャがそうであったように、見合った場所で人間が判断して使用すべき――あくまで1つの「ツール」なのです。
とはいえ、Strutsがある一定規模以上のアプリケーションを(特にチームで)開発する局面において、有力なツールであることは疑いようもありません。以下では、Strutsを用いるとどのようなことができるのか、われわれのどんな作業を効率化してくれるのかという観点から、Strutsの主要な機能を概観してみることにしましょう。
Strutsでは、機能を明確に分離するというコンセプト上、View(「 .jsp 」ファイル)にスクリプトレットや式構文(Expression)のようなスクリプティング要素を混在させるのは推奨されません。
そこでStrutsでは、独自のカスタムタグを提供することで、処理の分岐や繰り返し、エラー処理など、一般的によく利用されるような機能を「カスタムタグ」という形で提供しています。カスタムタグを利用することで、
<table border="1"> |
のように記述しなければならなかった「 .jsp 」ファイルも、以下のように記述することが可能になります。
<table border="1"> |
<%〜%>(または<%=〜%>)で囲まれたスクリプト部分が、すべてHTMLと同様のタグに置き換えられ、とても読みやすくなっているのがお分かりになるでしょうか。これならば、HTMLしか理解していない人間であっても、(比較的)抵抗なくレイアウトを編集することができます。
Strutsではこのようなカスタムタグを集めたライブラリを、あらかじめ用意しています。Strutsタグライブラリは機能別に、大きく5種類に分類されます。
タグライブラリ | 概要 | |
---|---|---|
HTML | <html:input>や<html:button>タグなどからなるフォーム部品。ほぼHTMLのフォームタグに対応するが、Modelで生成された値のデフォルト表示やエラー時のフィードバックなどリッチな機能を提供する | |
Logic | 条件分岐や繰り返し、値の比較など、プログラミング言語が提供する基本的な制御ロジックをタグ化する | |
Beans | Modelから引き継がれたJavaBeans(データオブジェクト)にアクセスするための手段を提供する。ヘッダ値やクッキーなど不可視のリクエストデータについても、Beansタグライブラリを介してアクセスすることができる。また、国際化対応メッセージを制御する | |
Nested | <nested:nested>タグで囲まれた内部の属性(変数)名を略記可能とします。例えば、「xxxx.yyyy.zzzz」のような変数を「zzzz」と記述することが可能になる | |
Tiles | テンプレート機能を提供する。Tilesを利用することで、ヘッダ、メニュー、コンテンツなどの部分から構成される画面を分割管理することが可能になり、デザインの統一を図りやすくなる | |
Strutsにおけるコアエンジンです。アクションサーブレットは、ユーザーが別に用意した設定ファイルを手掛かりにして、入出力データの振り分けや画面遷移の制御を一手に引き受けます。Strutsアプリケーションにおいては、このアクションサーブレットのおかげで、MVCのうちC(コントロール)の記述を限りなく省力化することが可能です。M(モデル)とV(ビュー)といったアプリケーション固有の機能開発に専念することができます。
ユーザーからの入力データを格納し、ビジネスロジックに引き渡すための役割を果たします。入力データの検証処理やデフォルト値のセットなど、これまでアプリケーション本流のロジックに混在しがちであった部分を一元的に管理することで、ビジネスロジックをスリム化することができます。
Struts 1.0.xまではユーザーが自らBeansクラスを記述する必要がありましたが、1.1以降では設定ファイルに引き渡されるデータの名前とデータ型を定義しておくだけで、あとはStrutsが内部的にデータの引き渡しを行うことができるようになりました(ダイナミックフォームBeans)。
「Validator」もまたStruts 1.1から導入された機能です。クライアントからの入力データを設定ファイルで定義された内容(検証対象、チェック内容、エラーメッセージ)に基づいて検証します。検証に際して、コーディングの必要は一切ありません。
Validatorには、デフォルトで必須チェック、文字列長チェック、正規表現チェック、データ型チェック、数値範囲チェックなどが用意されていますが、開発者が適宜必要に応じて拡張することも可能です。
そのほか、データベースへの接続を一元管理するための「DataSource」、クライアントの対応言語によって言語表示をダイナミックに切り替える「国際化( i18n )機能」、アプリケーションの初期化/破棄処理を行う「プラグイン」などなど、さまざまな機能が用意されていますが、これらについても連載の中で、順次紹介していく予定です。
Copyright © ITmedia, Inc. All Rights Reserved.