|
第4回
■■8.1 具象クラス■■ Javaによる具象クラスの実現例はリスト6のようになります
このJavaクラスAccountは典型的な具象クラスです。インスタンス変数はすべて可視性をprivateにして、外部からの不用意なアクセスを不可能にしています。インスタンス変数に対するアクセスはオペレーションを通して行うようになっています。 具象クラスAccountをUMLで表現したものが図13です。
Accountはコンストラクタを1つ定義しています。これをUML上で表現しているのが、ステレオタイプcreateを設定したオペレーションAccountです。 withdrawメソッドはthrows句で送出する可能性のある例外としてIllegalArgumentExceptionを宣言しています。このようなオペレーションと例外の関係はsendディペンデンシィで表現されます。 例外はステレオタイプexceptionを設定したクラスとして表現されます。IllegalArgumentExceptionはjava.lang.RuntimeExceptionの子孫クラスであり、検査なし例外と呼ばれているものです。この点をプロパティruntimeで表現しています。 ■■8.2 抽象クラス■■ 抽象クラスの実現例はリスト7のようになります。
このJavaクラスAbstractItemは典型的な抽象クラスです。抽象クラスはクライアントオブジェクトから直接生成されることはないので、コンストラクタの可視性をprotectedにしています。 抽象クラスにつきものの抽象メソッドであるgetPriceを定義しています。また、getIdメソッドがfinalとなっており、サブクラスでのオーバーライドを許さないことが明示されています。抽象クラスAbstractItemをUMLで表現したものが図14です。
クラス名AbstractItemがイタリック体で表示されており、AbstractItemが抽象クラスであることを示しています。抽象メソッドgetPriceもイタリック体で表示されています。 コンストラクタはステレオタイプcreateのオペレーションで表現されています。可視性protectedもそのままUMLで表現されています。 getIdメソッドのfinalは、プロパティfinalとして表現しています。ここを標準プロパティleafで表現することも可能です。 ■■8.3 インターフェイス■■ インターフェイスの実現例はリスト8のようになります。
インターフェイスIItemをUMLで表現したものが図15です。
図15は、ステレオタイプinterfaceを用いてインターフェイスであることを表現しています。インターフェイスは、それ自身がインスタンス化されることはなく、また定義してあるオペレーションはすべて抽象オペレーションとなります。通常のクラスであればインターフェイス名やオペレーションは、プロパティabstractを明記するか、オペレーションをイタリック体で表示するところですが、インターフェイスの場合は、通常の表示のままでよいことになっています。 ■■8.4 インターフェイスと定数■■ 定数を使ったインターフェイスの実現例はリスト9となります。
setPriorityメソッドやgetPriorityメソッドで扱うint型のデータに用いる定数としてPRI_HIGH、PRI_MIDDLE、PRI_LOWの3つを定義しています。このインターフェイスIScheduleableをUMLで表現したものが図16です。
定数はUMLの仕様外です。属性で表現することもできなくはありませんが、ここでは定数用のオプションの並び区画を設け、そこにJavaの文法の文字列を記述するという方法を用いています。 ■■8.5 ユーティリティ■■ Javaによるユーティリティの実現例はリスト10となります。
このユーティリティCalcをUMLで表現したものが図17です。
定義されているオペレーションはすべてクラススコープなので通常のクラスであれば下線を引いて表現するところですが、ユーティリティの場合は、普通のオペレーションと同様の記述でよいことになっています。 ■■8.6 ファクトリ■■ インスタンススコープのオペレーションとクラススコープのオペレーションが混在する例として、ファクトリオブジェクトについて考えます。Javaによるファクトリの実現例はリスト11となります。
ファクトリでは、オブジェクトの生成を自分自身のクラスメソッド(この場合はnewInstance)でしか行えないようにすると危険防止になるので、コンストラクタをprivateにしています。 変数factoryとメソッドnewInstanceはいずれも修飾子staticが指定されており、それぞれクラス変数とクラスメソッドであることが宣言されています。 ItemFactoryをUMLで表現したものが図18です。
属性factoryやオペレーションnewInstanceに下線が引かれておりクラススコープの属性やオペレーションであることを示しています。 ■■8.7 内部データ■■ パッケージ内で利用するデータを格納するためのオブジェクトについて考えます。 Javaによる実現例はリスト12となります。
パッケージ内で利用するデータなのでクラス本体、オペレーションの可視性をパッケージにしています。クラス本体の可視性は、パッケージ外からのアクセスに対する可視性ということになります。また、内部データ用のオブジェクトなので属性をオペレーション経由ではなく、 直接外部から操作できるようにしています。 クラス本体の可視性の表現は、クラス名の前に可視性を示す記号を表示することで行います。「パッケージ内」の可視性を表現するためにUML 1.4から導入された新機能である「~」を使用しています(図19)。
◆ “クラス”は、UMLとJavaでほとんど同じ構造になっているので、簡単なクラス図を書くことが目的であればマッピングは比較的簡単に行えます。しかし、CASEツールでの自動マッピングなどをターゲットにして、厳密にマッピングを考えていくと、UMLの複雑な部分も見えてきます。UMLの仕様が膨大であるうえに、UMLとJavaのモデルが微妙にズレている点もあるからです。この問題に対応するためには、Javaとのマッピングに使用するUMLの仕様を絞り込んだうえで、UMLの仕様にないJavaの機能をステレオタイプやプロパティなどの拡張メカニズムを使って、拡張していく必要があります。もちろん、このような拡張を行う場合には、用途に応じてプロファイルとしてまとめていくことが必要です。そして、このプロファイルを開発チームの中でのルールとして利用することで、UMLを用いたコミュニケーションを円滑に行うことができるようになります。 今回は、オブジェクトの核となるモデル要素であるクラスについて、JavaとUMLのマッピングを検討するために必要な論点を明らかにしたうえで、サンプルのプロファイルを作成してみました。このプロファイルは筆者の好みが大きく反映されていますが、一般的な開発ではそのまま利用できるのではないかと思います。もちろん、実際の開発に当たっては、利用するCASEツールとの整合性といった要因を考慮に入れてチューニングしていくとよいでしょう。
|
[an error occurred while processing this directive] |
||||||||||||||||||||||||||||||||||||||||||||||||||







