ケース別のメリット解説(2)
問題3:ページのデザインの取り込み
お客さまの商品情報サイト内の通信販売やアンケートなどのWebサイト構築では、デザイナーさんが主導権を持つケースも多くなります。その場合、静的なページや入力フォームを囲むフレームのデザイン、スタイルシートをデザイナーさんに任せ、入力フォームはSE側が担当するのが理想です。しかし、入力フォームまできれいにデザインされたモックアップが出てくることもよくあります。そのうえ、デザインと開発が並行して進んでいることもあるので大変です。そのような場合、以下のような事象が発生します。
SE A:今回はプレゼント応募サイトなので、デザイナーさんたちは揉めているね。
SE B:どうせ個人情報の入力させるフォームがメインなんだから、システムはさっさと作ってしまおう。
SE A:さてテストも終わったぞ。
デザイナー:やっとデザインがあがりました。これをシステムに取り込んでください。
SE A:JSPにはいろいろスクリプトが入っているから、スタイルを一つ一つ組み込んでいくしかないか。
SE B:このカスタムタグが出力するHTMLのタグって何を出力してるの?HTMLソース表示してもぐちゃぐちゃで読みづらい。
SE A:タグが変わったから、スクリプトも影響を受けそうだ。こりゃ再テストになるな。
SE B:やっとテストが終わったぞ。
デザイナー:あのー、この画像の位置がちょっとずれているので、デザイン通りに修正してください。
この事例の問題点は、Viewの定義がHTMLそのものではないという点に尽きると思います。各種フレームワークでは、カスタムタグやカスタムアトリビュートで便利な機能が提供されています。しかし、デザイナーさんにとっては「なにそれ?」という存在です。これらの便利機能を使うと、デザインの取り込みはSEでないとできなくなってしまいます。また、HTMLやJSPなどのViewの定義ファイルにスクリプトを記述してしまうと、なおさらSEでないと手出しができないものとなります。
「普通、デザインが決定してから開発するものではないのか?」という声が聞こえてきそうですが、現実は厳しいです。理想的なスケジュールを組めるプロジェクトばかりではありません。
また、ある程度システムを運用した後、「サイトのイメージチェンジのためデザインだけリニューアルしたい」なんて要望も出たりします。このような場合も、既存のフレームワークでは技術者の作業量が多くなります。
dataforms.jarでは、スクリプトが一切記述されていない純粋なHTMLを、そのままViewとして使用します。HTMLにはonclick等のイベントハンドラも一切書きません。また、特殊な機能を割り当てたアトリビュートを記述することもありません。
dataforms.jarでは、まずJavaのページクラスを作成します。ページクラスには複数のFormクラスを配置し、そのFormクラスには各種フィールドクラスを配置します。dataforms.jarの開発ツールを使うと、このようにして作られたページクラスから自動的にHTMLを生成することができます。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="mainDiv"> <form id="queryForm"> <div class="formHeader">検索条件</div> <table class="responsive"> <tbody> <tr> <th>テキスト</th> <td><input type="text" id="sampleText" /></td> </tr> <tr> <th>数値(from)</th> <td><input type="text" id="sampleNumFrom" /></td> </tr> <tr> <th>数値(to)</th> <td><input type="text" id="sampleNumTo" /></td> </tr> <tr> <th>日付(from)</th> <td><input type="text" id="sampleDateFrom" /></td> </tr> <tr> <th>日付(to)</th> <td><input type="text" id="sampleDateTo" /></td> </tr> </tbody> </table> <input type="submit" id="queryButton" value="検索"> <input type="button" id="resetButton" value="リセット"> <input type="button" id="newButton" value="新規登録"> </form> <form id="queryResultForm"> <div class="formHeader">検索結果</div> <input type="hidden" id="sampleId" /> <table class="responsive"> <tbody> </tbody> </table> <div class="hScrollDiv"> <table id="queryResult"> <thead> <tr> <th> No. </th> <th> テキスト </th> <th> 数値 </th> <th> 日付 </th> <th> 操作 </th> </tr> </thead> <tbody> <tr> <td> <span id="queryResult[0].rowNo"></span> <input type="hidden" id="queryResult[0].sampleId" /> <input type="hidden" id="queryResult[0].createUserId" /> <input type="hidden" id="queryResult[0].createTimestamp" /> <input type="hidden" id="queryResult[0].updateUserId" /> <input type="hidden" id="queryResult[0].updateTimestamp" /> </td> <td> <a id="queryResult[0].updateButton" href="javascript:void(0);"><span id="queryResult[0].sampleText"></span></a> </td> <td> <span id="queryResult[0].sampleNum"></span> </td> <td> <span id="queryResult[0].sampleDate"></span> </td> <td> <input type="button" id="queryResult[0].viewButton" value="表示"> <input type="button" id="queryResult[0].referButton" value="参照登録"> <input type="button" id="queryResult[0].deleteButton" value="削除"> </td> </tr> </tbody> </table> </div> </form> <form id="editForm"> <div class="formHeader"><span id="editFormTitle"></span></div> <input type="hidden" id="sampleId" /> <input type="hidden" id="createUserId" /> <input type="hidden" id="createTimestamp" /> <input type="hidden" id="updateUserId" /> <input type="hidden" id="updateTimestamp" /> <table class="responsive"> <tbody> <tr> <th>テキスト</th> <td><input type="text" id="sampleText" /></td> </tr> <tr> <th>数値</th> <td><input type="text" id="sampleNum" /></td> </tr> <tr> <th>日付</th> <td><input type="text" id="sampleDate" /></td> </tr> <tr> <th>選択</th> <td><select id="sampleSelect"></select></td> </tr> </tbody> </table> <input type="button" id="confirmButton" value="確認"/> <input type="button" id="saveButton" value="登録"/> <input type="button" id="resetButton" value="リセット"/> <input type="button" id="deleteButton" value="削除"/> <input type="button" id="backButton" value="戻る"/> <input type="button" id="printButton" value="印刷"/> </form> </div> </body> </html>
このページをSamplePage.htmlではなく、SamplePage.dfというパターンでアクセスすると、dataforms.jarの中のDataFormsServletが動作し、以下のようなソースが出力されます(このページ内では一部省略しているので、完全なものはサンプルファイルでご確認ください)。
<!DOCTYPE html> <html> <head> <!-- dataforms.jar Java web application framework (C) 2015,2016 Masahiko Takayanagi. Licensed under the MIT license. --> <!-- スマートフォン対応 --> <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no,maximum-scale=1" /> <!-- jquery,jquery-ui等のスタイルシートとjsライブラリを展開する --> <link type="text/CSS" href="/dfsample/jquery-ui/jquery-ui.min.css" rel="stylesheet" /> <script type="text/javascript" src="/dfsample/jquery/jquery.min.js"></script> <script type="text/javascript" src="/dfsample/jquery-ui/jquery-ui.min.js"></script> <script type="text/javascript" src="/dfsample/jquery-ui/datepicker-ja.js"></script> ・・・中略・・・ <script type="text/javascript" src="/dfsample/frame/default/SideMenuForm.js?t=20160530143354"></script> <script type="text/javascript" src="/dfsample/frame/default/LoginInfoForm.js?t=20160530143354"></script> <script type="text/javascript" src="/dfsample/frame/default/Frame.js?t=20160530143354"></script> <script type="text/javascript"> <!-- $(function() { var page = new BasePage(); window.currentPage = page; page.init(); page.attach(); }); --> </script> <meta charset="UTF-8"> <title></title> </head> <body> ・・・中略(Servletの出力する<BODY>部はSamplePage.htmlの<BODY>と同じ)・・・ </div> <noscript><br/><div class='noscriptDiv'><b>Javascriptを有効にしてください。</b></div></noscript> </body> </html>
このソースを見てもらえばわかると思いますが、後半のHTMLは開発ツールで作成したHTMLがそのまま出力されています。前半にはdataforms.jarが提供するJavaScriptクラスライブラリとその初期化スクリプトか出力されています。
HTML部分にはonclickなどのイベントの記述は一切ありませんが、データの検索や登録、更新等の機能が動作します。不思議に思われるかもしれませんが、その秘密は出力された数行の初期化スクリプトにあります。この初期化処理では、ページのJavaクラスで定義されたページの構成を取得し、その情報を元に各種フォームやフィールドに対して適切なイベント処理を設定します。
ServletやJSPは、サーバーで動的にHTMLを生成してブラウザに送信するものでした。しかし、dataforms.jarが行う編集は、HTMLに初期化スクリプトを追加するだけです。ページの表示内容を書き換えるのは、JavaScriptのクラスライブラリが担当します。JavaScriptの各種フィールドクラスのサブクラスを作成すれば、カスタムタグのような便利機能を作成することもできます。dataforms.jarはこのような仕組みを持つため、単純なHTMLをそのままViewとして使用できるようになっています。
以前、デザインとシステム開発が同時進行するようなプロジェクトで、デザイナーさんにEclipseとSVNの使い方を伝授し、デザインを進めてもらったこともあります。参加するデザイナーさんがHTMLの文法を理解している必要がありますが、これが開発の理想的な形だと思っています。デザインが先行しHTMLのモックが提供されている場合でも、JSP等を使用したシステムより簡単にデザインを取り込むことができます。
また、ページの初期化スクリプトは、あらかじめ設定されたフレームを配置します。このフレームのデザインも単純なHTML、CSSで行います。できればデザイナーさんの編集範囲はこのフレームのHTML、CSSにとどめておく方が安全でしょう。
現状、デフォルトのフレームには私が仮にデザインしたものが入っています。フレームはweb.xmlの設定で切り替えることができますが、今のところフレームは1種類しかありません。デザインに自信のある方はフレームのデザインを作ってみてください。良いものができたら、公開していただけるとありがたいです。