Kandataを作った動機と実現するための設計
動機
世間の流れからするとチョット遅いのですが、私も最近Webアプリの開発を行うようになりました。
しかし、どうもこのWebアプリが好きになれませんでした。
今までのスタンドアロンのアプリに比べると、Java,HTML,Servlet,JSP,JavaScriptなど
覚えなければならない要素技術が多いです。
それに開発環境が貧弱、デバッグも困難、不具合が発生しても問題の切り分けに苦労します。
そのような苦労をして開発し、できたアプリがすばらしいかというと、そうでもなさそうです。
コントロールの種類も少ないですし、とにかくGUI周りの細かい制御ができません。
利用できる機能が限られているので、利用者にとっても良い環境とは思えません。
そのように感じるのは私だけでしょうか?
時代の流れでこのようなWebアプリが主流になってしまったけれど、
今のこのカタチが最適な形だとはどうしても思えませんでした。
もしそれらを考慮せず、1からWebアプリを考えたらどのようなカタチになるのでしょう?
それが、Kandataを開発するようになった動機です。
既存技術の分析
(あまり詳しくないので、間違っている箇所があるかもしれません。)
HTML+サーブレットの場合
必要な画面だけをクライアントに送っているので、軽い。
起動時は、Webブラウザを起動し、最初の画面だけを取得するので速い。
すべての画面、アプリ全体をダウンロードしているわけではない。
HTMLは覚えるのが楽。
ちょっとした画面表示の変更でも、サーバ側と通信し、画面全部の情報を取得し、再表示しなければならないので無駄。
フォームで使えるコントロールの数が少なすぎる。トグルボタンやツリー、スプレッドシートなどがない。
メッセージBOX、ダイアログなど、ウィンドウに関係したAPIがほとんどない。
ウィンドウの親子関係の指定ができないので、モーダルダイアログが作れない。
ウィンドウ破棄のイベントがない。セッションの切断の正しい判断ができない。
アドレス直入力、戻るボタンにより、想定された画面遷移以外の動きをしてしまう。
Webブラウザの設定を変えれば、JavaScriptが使えなかったり、Cookieが無効になるので、意図した動作をしない。
Webブラウザのバージョンの違いにより、HTMLタグなどが使えるものと使えないものがある。共通のものを使うか、ブラウザのバージョンを限定しなければならない。
Webブラウザの種類や設定で見栄えが変わる。
クライアントマシンは年々高性能になるので、Thinクライアントにしなければならない理由はない。
クライアントの資源を有効に使っていない。
例えば、Strutsの場合、ActionFormやJSP、TagLibなどはクライアントの制御であって、
本来サーバ側で行う処理ではない。
開発に必要な要素技術が多くて大変。(Java,HTML,JavaScript,Servlet,JSP,Struts,TagLib...)
JSP,JavaScriptなどデバッグが困難。1つのファイルに複数の言語が混在しているため。
アプレットの場合
起動が遅い。巨大アプリには向かない。
IEのデフォルトのJavaVMは古い。
セキュリティ上、利用可能なAPIが制限される。
Webブラウザ内で動くので、ウィンドウを複数起動することができない(ホント?)
クライアントアプリをサーバからダウンロードする場合
ダウンロードに時間がかかる。巨大アプリには向かない。
バージョンアップの仕組みを考える必要がある。
Java以外だとプラットフォームに依存してしまう。
じゃあどうすればいいか?
Webブラウザを使わない(これが元凶のような気がする)
HTMLは使わない。
JavaやXMLなど、プラットフォームに依存しないスタンダードな技術を使う。
クライアントアプリは、サーバ側から取得するようにする。
クライアントは一気に取得するのではなく、必要なモノだけをその都度取得する。
GUIの操作など人間とのやりとりの部分はクライアント側で行う。サーバ側はクライアントの操作を気にする必要はない。
その都度ダウンロードするものは、画面と、画面を制御するためのロジック。
クライアントに最初にあるのは、とても小さなJavaでできたランチャーで、これは
アプリに依存しない。
ランチャーの機能は、サーバ側に接続し、最初のエントリの画面+ロジックをダウンロードし、それを起動する。
それ以降の処理はアプリによって行われる。
サーバとの通信は、サーバの負荷を減らすため必要最小限にする。サーバはActionのみを実装する。
画面制御、入力チェックなど、クライアントでできるものはクライアント側で行い、操作性をよくする。
クライアントはサーバに対し、Actionの要求を送ることができる。それに対しての結果を取得する。
クライアント起動時にサーバに接続し、終了時に必ず切断するようにすれば、正確なセッションを張ることができる。
そこから導き出される大雑把なモデル
クライアントにはあらかじめ小さなJavaアプリのみがある。
URLを指定してサーバに接続する。
最初に起動すべきクライアントの画面+ロジックを取得する。
その最初の画面を起動させる。
それ以降の画面+ロジックを必要に応じてサーバから取得する。
サーバに対して要求を送り、結果を取得する。
終了時には切断したことをサーバに通知する。
サーバの機能
クライアントからの要求を受け付け、処理を行った後、結果を返す。
エントリの画面+ロジックを返す。
その他の画面+ロジックを返す。
その他のリソースを返す。
サービスを提供し、クライアントからの要求を処理する。(必要ならDBなどにアクセスして)
現状の技術を使い、どうやって実現するか考える
画面+ロジックはどうするか?
HTML+JavaScript。
それ以上のものを考えているので没。
XMLで画面とロジックを記述する。
ロジックをXMLで書くのはツライ。
やはり、ロジックはプログラム言語で書くべき。
XMLで画面を記述し、その中に独自スクリプトを入れる。
新しいスクリプトを定義し、それを作らなくてはならない。大変。
新しいスクリプトを作っても、利用者がそれを新たに覚えなければならないのでは
あまり意味がない。
(古い苦労を取り払っても新しい苦労を強いてしまう。)
Java完全互換なスクリプトならいいかもしれない。
XMLで画面を記述する。ロジックは別ファイルで書く。(2ファイル)
かなりイイ。
ロジックはJavaで書くことにする。
XMLはVBの*.FRM、ロジックはVBの*.BASにあたる。
XMLから画面を作成するビルダーが必要。
classファイル
SwingやSWTを使って開発されたクラスファイル。
画面とロジックを含んでいる。
バイナリファイルなのが少し気になる。
GUIライブラリは開発者が選ぶことができる。
Javaソースファイル
classファイルをコンパイルする前のものを送る。
クライアント側でその都度コンパイルすれば可能。
処理が重くなりそうな気がするが、JSPはそれをやっているので
まったく非現実的なわけではない。
後ろ3つはどれも甲乙つけがたいです。
結局、実現が容易な classファイルにすることにしました。
ただ、あとで変わっても容易に変更できるようにしておきます。
通信部分はどうするか?
通信は、RMIやHTTP、独自ポートなどいろんな方法が考えられます。
とりあえずHTTPで実現する方法を考えます。
HTTPなら現状のインターネットの環境で、容易に使えるのではないでしょうか?
Webサーバからみればサーブレットの1つに見えます。
クライアント側はファイアウォールなど気にせずそのまま使えるハズです。
ただし、必ずしもHTTPでなければならないわけでもないので、
他の方法でも置き変えれるようにしておきます。
通信手段はこだわっていません。
サーバへの要求と結果の取得
とりあえず、
Object invoke(String command, Object[] args) throws Exception
の形のAPIを用意します。
この1つのAPIさえあれば、エントリクラスの取得やりソースの取得、サーバへの要求など
いろんな目的に使えるでしょう。
サービスの要求は、スタブを作ればもう少し使いやすくなるけれど、
それはあとで考えます。
まとめ
HTTPを使うため、Tomcatを採用します。
Tomcatのセッション管理も利用できるかもしれません。
Kandataサーバはサーブレットとして実装されますが、
サーバアプリを開発するときは、それを意識する必要はありません。
クライアントモジュールをクラスファイルの形でサーバ側からダウンロードするため、
HTTPを使ったクラスローダを自作します。
クライアントのGUIライブラリは特に限定していないので、SwingでもSWTでもAWTでも、
あるいはコンソールアプリでも構いません。開発者は好きなライブラリを選ぶことができます。
より詳細なデザイン
クラス図
各インターフェース
シーケンス図
他に考えなければいけないこと
国際化。日本人には日本語のアプリを。
→起動時にクライアント側のLocaleを渡す。
クライアントマシンの種類により、送信するクライアントアプリの種類を変える。
例えば、Swing版、SWT版、携帯版(?)
(そういう要望は出てくるか?)
セキュリティを考えたほうがいいのでは?
サーバに送った方がよいクライアントの情報は?(Javaのバージョンなど)
簡単にデバッグできる環境
Tomcatを起動しなおさなくてもよいように、HTTPを介さずに直接サーバを呼べるテスト用モジュールを用意する。
クライアント/サーバ型ではなく、スタンドアロンの1アプリにしてしまう。
JBuilderやEclipseなどのデバッグ機能が使える。容易にデバッグができるようになる。
バージョンアップの問題をどうする?
以下の3つが考えられる。
Kandata自体のバージョンアップ。
サーバ側のバージョンアップ。
クライアントモジュールのバージョンアップ。
開発支援、サーバ管理のためのツールを用意する。
ログ出力、ログ閲覧。クライアントの接続数や上限値の設定。
クライアントコンテキストの閲覧。クライアントの強制切断。
サーバの動的な設定値の変更。などなど。
サーバ側で発生したイベントをクライアントで受けることはできないか?
PUSH型、コールバック型、イベント駆動型、poll()、ConnectionPoint。
(そもそも、そういう要望は出てくるか?)
最初にaddListener(xxx, xxx)で登録。切断時には自動削除。
HTTPベースではムリ?
戻る