[Jude開発記]
去る1999年7月30日に私達は,Jude(Java and UML Developers' Enviroment)というUMLダイヤグラムエディタをフリー公開しました。Judeは、JavaTM言語とUML(Unified Modeling Language)によるオブジェクト指向設計を支援するツールです。ここでは、Judeの設計、方針、苦労話、ぶつかった問題などなど、公開に到るまでの記録を開発事例として紹介します。オブジェクト指向開発を実際に行っている方々、特にJavaを利用して対話型アプリケーションを作成する際のヒントになれば幸いです。
1997年12月、JOMT(ジョムト)というコードネームでJudeの開発プロジェクトはスタートしました。手軽に使えるOMTツールがなかったことGUIを持つグラフィックアプリケーションを一度作って見たかったこと、javaが盛り上がっていたこと、などが開発の動機になっています。
JOMTという名前からも分かるように、そのころまだ UML は成熟しておらず、OMTが最も名の通った方法論だったのです。開発後期に、JOMTはJudeと改名しました。
最初に以下の方針を立てました。
【フレームワーク】
最初からアプリケーションを作るのではなく、最初にMVCフレームワークを作成することから始めました。あわよくばJudeだけでなく、今後作るアプリケーションの土台を作ろう、という目論見です。おそらく、このようなアプローチは最近はよく行われているものだと思います。どのようなアプリケーションでも、必ず再利用可能な可能性がある部品が作成されます。レイヤーを明確に区切ることで、意識的に再利用部品をメンテナンスすることができます。
汎用GUI MVCフレームワーク |
このフレームワークは、Golf(ゴルフ)と名付けました。GolfはGraphics-Oriented Lightweight Frameworkの略です。基本的にJDK1.2上(Swing、Java2Dを含む)に、MVCを意識したフレームワークを構築しています。
フレームワークとして取り組んだ点は、
以下に、クラス図の中の代表的なクラスについて、その役割を解説しました。
カテゴリ | クラス名 | 責務 |
Model | Entity(StateEditable) | 問題領域のデータモデルの単位。Entityはswing.undo.StateEditableである。 |
EntityStore | データ管理コンテナ。Entityを管理する。EntityStoreはEntityの編集トランザクションを管理していて、永続化、異常時のアボート、ロールバックや、Undo/Redo の機能を持つ。 | |
EntityStoreEvent | EntityStoreへの一回のトランザクションが終了すると、EntityStoreはこのクラスのオブジェクトを発火する。 このイベントのリスナは主にViewカテゴリである。 | |
View | ViewManager | Viewとなるウィンドウ等全体の管理を行う。ViewManagerは、すべてのGUI部品を辿るルートとなるSingleton。 |
UIView | swingのJComponentを保持するクラス。現在選択されているEntityを管理する機構を内蔵する。またEntityStoreからのEntityStoreEventを受け、自分自身の表示を書換えることができる。 | |
GCanvas | Java2Dを利用した、グラフィックキャンバスretain型の表示を行う。 | |
Controller | CommandEvent, CommandListener | コマンドが発行されたことを示すイベントクラス。CommandEventは、主にViewから生成されるが、マクロ言語などを組み込んだ際は外部的に発生させることもできる。CommandListenerは、このCommandEventを受け付けるインターフェイス。 |
CommandManager | コマンドを管理するSingletonクラス。CommandListnerを実装し、外部からのCommandEventを受け付ける。 | |
Command | すべてのコマンドの、スーパークラス。このクラスを拡張して、アプリケーションの問題領域の具体コマンドクラスを作成する。 | |
Mode | 実際にGUIイベントを補足し、それをコマンドに変換する機構。Modeは各UIViewに登録され、状況によってCommandEventを発生。ドラッグやラバーバンド等のフィードバックもModeで行われる。 | |
Application | このクラスは、mainメソッドを持つ、最上位のSingletonクラス。実際のユーザアプリケーションは、このクラスを拡張して具体アプリケーションクラスを定義する。 |
特に凝った点は、随所にjavaのイベントモデル(MultiCastパターン)を用いている所でしょうか。MultiCastパターンはObserverパターンに比べて型安全なので、多くの場面で有用でした。
例えば、モデルからビューの更新や、GUIイベントのCommandイベントへの変換等で使用しています。(MultiCastパターンについては、お世話になった本〔4〕を参照)
【Undo/Redo】
Undo/Redoの実装としては、GoFのCommandパターン、Mementoパターンを思い出す方が多いと思います。これは、CommandクラスのメソッドとしてdoIt()、undoIt()、redoIt()を持たせるものです。
しかし、この方法だとCommandサブクラス実装者に負担が掛かります。また、コマンドによってundoできるものとできないもの、という不整合も起こりがちです。
そこで、Golfでは、データ管理の責任者であるEntityStoreが一括してUndo/Redoの面倒を見てくれるようにしました。EntityStore内のデータに対する編集は、追加、削除、修正に分類されてトランザクションごとに履歴として記憶され、1トランザクションをundo/redoの単位としました。この手法は、javax.swing.undoパッケージのクラスの仕組みにうまく載せることができました。
Undo可能な編集は、1つのUndoableEditとしてまとめられ、UndoManagerへ投げられます。ここでもMultiCastパターンが登場します。
【モデルとそのFacade】
UMLを表現するモデルを自分達で新しく構築するのは困難であり、Rational社より公開されているメタモデル仕様を忠実に実装しました。
メタモデルでは、多重継承が使用されているところがいくつかあります。ところが、Javaは多重継承を許さないため、すべてのモデルに対して(javaの)インターフェースを作成して、対応することにしました。
モデルはこれで整うのですが、実際これを利用するにはまだ複雑でした。例えばクラスのモデルをひとつ作成するだけでも、親のパッケージモデルとの関連をつないだりなど複数の作業を行わなければなりません。そのため、メタモデルの複雑な構造をカプセル化し、モデルの利用を簡単に行うためのモデルのFacadeを作成しました。それは以下のような役割を持ちます。
【モデル情報、図情報、ビュー情報の関連】
Judeで作成するファイルに保存するデータとしては、上記のモデルの情報と、またそのアイテム(表示される絵)の位置情報など図の情報とがあります。
MVCにおいて、MとVをわけて考えようという思想と同様に、モデル情報と図情報をわけて考えました。
ModelElement、Presentation、Diagramはモデルに属し、永続化可能なオブジェクトです。これに対して,ViewElementはテンポラリな情報であり、ModelElementとPresentationから組み立てることができます。
ここで要求されることは、
【自動レイアウト】
自動レイアウトは、ユーザが描いたクラス図を適当に美しく配置しなおしてくれる機能です。ここでは、クラスなどのアイテムを先に配置し、その後関連線などのアイテム間の線を整えるという方法をとりました。アイテムの配置方法は、
自動レイアウトはまだまだ研究の余地があります。「綺麗」という判断基準が見る人によって違うのも、この問題を難しくします。将来は、幾つかの配置ポリシーやパラメータをユーザに選んでもらうような方法にして行きたいと思っています。
【JavaCCの利用】
RationalRoseで提供されているファイル(mdlファイルなど)の読み込みには、パーサを用意する必要がありました。これには、JavaCCを利用しています。JavaCCを使えば、一から自分で構文解析のコードを書くよりは楽です。しかし、JavaCCはかなり大きなコードを吐き出すので、その結果JavaCC から作成されたコードは、Jude全体の1/7のステップ数をしめたことには驚いています。
【ユーザーインターフェースの構築】
リソース(テキストファイル)を読み込み、それをもとに自動的にメニュー、ボタン、ツールバーを構築するクラスを作成しました。コンパイルをせずに、リソースファイルを編集するだけでメニューの構成を変更でき、デバッグコマンドの追加などにも役にたちました。
ロゴ、アイコンなど画像はすべてチーム内で加工されました。特に、ロゴ(Jude Home Pageの先頭)は開発者みんなが墨と筆で書道を行い、スキャナーでとりこみ、コンテストしました。
開発の工程管理、成果物の指針は、NJKのDropを採用しました。開発を始めた時点で、成果物となる仕様書の書き方や項目について、日本語で規定していたオブジェクト指向方法論がDropでした。現在では、Rational Unified Processなどのメジャーでスタンダードなプロセスも候補になるでしょう。
【Java開発環境】
開発マシンは、LANに繋がれたUNIXとWindows NT、95、98です。Java 環境はJDK1.2+エディタ(mule、meadow)という原始的な組合せです。IDEは特に使用しませんでした。
【ソースコード構成管理】
CVSを使用しました。特に開発マシンがUNIXとWindowsが共存していたので、UNIX上にCVSリポジトリを置き、sambaでファイル共有しました。また、仕様書類もすべてテキストファイルを基本として CVS で管理しました。
最近、WinCVSというフリーの大変使いやすいGUIベースのCVSツールが出ています。sambaとの相性もよく、改行などのWindows<->UNIX変換も自動的に行ってくれるようです。さらに、UNIX上にはApacheを置いて、仕様書をWindowsのブラウザから見えるようにしました。
【設計ツール】
UMLダイヤグラムの作成に、Rational Rose 98を使用しました。市販のオブジェクト指向CASEツールとしては最も高機能で安定しているものです。Judeは最終的にはこの商品のライバルとなることを目指していますが、まだ道のりは遠いようです。コードができ始めてからは、javadocを毎晩走らせ、HTMLでのドキュメントを更新しました。共通で使用するパッケージの仕様などがブラウザで見れて便利でした。また、javadocにはDocletという機能があり、HTML 以外の形式でもソースコードから設計情報をとり出せるようになっています。RoseDocletを自作して、javaソースからRational Roseのモデルデータを取り出すことも行いました。Rose のリバースエンジニアリング機能でも同等のことができます。
【バグ管理】
メールと組み合わせたGNUのバグ管理ツール、gnatsを使用しました。
開発にあたって、よく参照したページを紹介します。
UML Resource Center | UMLに関するドキュメントはここよりダウンロード |
JavaHouse MLのアーカイブ | Javaで行き詰まったときは、ここで過去の記事を検索 |
オブジェクトの広場 | ご存知、オブジェクト指向フリークの集う場所 |
じゃばじゃば | あさみさんのページ。JavaとUMLのことについて詳しく書かれています |
統一模式化言語友の会 | 初期のUML研究会 |
オブジェクト指向方法論Drop | 日本発のオブジェクト指向方法論 |
Java To Rose | javaソースからRational Roseのモデルデータを作成するツール |
Javaのテキスト | JDK1.2のCollection、javaプログラマのためのUML入門など |
開発中に特にお世話になった本を挙げておきます。最初の2つはUMLメタモデルを理解、解釈する際に読みました。
UMLモデリングのエッセンス | Martin Fowler、Kendall Scott著 |
UML ガイド | H.E.Eriksson、M. Penker著 |
デザインパターン | Erich Gamma、他3名著 |
Pattern Hatching | John Vlissides著 |
以上、駆け足でJudeの開発を振り返って書いてみました。Judeの無償ダウンロードと機能説明について詳しくは、
https://www.esm.co.jp/divisions/open-sys/Jude/
からどうぞ。
最後に、開発に携わった全員に、それぞれ最も苦労した点をコメントして頂き、クレジットに替えます。
●フレームワークの設計がなかなか固まらず何度もやり直したこと(Javaがすき:Java2D)
●テキスト罫線出力のアルゴリズムの実装は結構苦労した。でもこの機能の設計はなかなか楽しく、わりにいい出来なので満足してます。(ちゃまだ:開発チーフ)
●ダイアグラム上での細かい操作に対応するコマンド機構の設計に悩みました。図情報の複雑さへの挑戦も手強かった。(越前ガニ:Model-View担当)
●苦労した点は、自動レイアウトでの配置位置の決定方法(アルゴリズム決定まで)。どの部分からどのように配置していけば、たいていのケースにおいて綺麗に見えるのかの検討。(りすちゃん:自動配置担当)
●Golfの中でも、UI部分構造を決めるのに苦労した(ような気がする)。(ume:UI担当)
●苦労した(???)点、それは画像アイコン作成。色や見ための統一感。少ないドット数での機能の表現。(GEN:アイコンデザイン担当)
●方針を決める時に、言語は本当にJavaでいいのか悩んだ。C++ならもっと軽快なソフトになったのでは、と途中何度も思ったが、JDK1.2が提供してくれたライブラリのおかげで、かなり開発は楽だった。(KH:プロジェクト管理担当)
© 1999 OGIS-RI Co., Ltd. |
|