@IT情報マネジメント会議室は、2009年4月15日に新システムに移行しました。
新たに書き込みを行う場合には、新しい会議室をご利用ください。
新たに書き込みを行う場合には、新しい会議室をご利用ください。
- @IT情報マネジメント 会議室 Indexリンク
- IT戦略
- 仕事の改善
- アーキテクチャ
- プロジェクト管理
- ITインフラ
- Webマーケティング
- BPMプロフェッショナル
- 業務アプリ
- - PR -
UML:関連クラスの誤解について
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2004-12-28 02:02
大歩危をかましているかも知れませんが。分析や設計を考えた際の関連クラスの見方が皆様と僕とで違う様なので投稿致します。
関連クラスは、単に線で定義した関連よりはもう少し具体性を提示し、その気になれば普通のクラスに等価展開出来る状態だが、関連クラスの段階では実装に影響を与えない物だと受止めています。 業務系システム開発における(主に)分析行為や設計行為では概念の存在を認識しているが、実装対象外とする事があります。 この際、実装対象外に決断したからと言って、一旦認識した事を分析行為や設計行為の記録から抹消する事はありえず。それより存在を認識し如何いう機構か理解した上で対象外の決断を行った事を記録する事が非常に重要になります。 この時に「関連クラス」が生きてくるのでは無いでしょうか? 例えば、売上と請求の関係を『売上伝票を集約して請求書を作成する。』だけで捉えた業務システムが多いですが。もう少し分解させると『(1)売上行為を売上伝票で記録し、(2)売上行為によって債権が発生し、(3)発生した債権を債権先と取決た契約に従って、(4)債権を集計し請求書を起こし、(5)請求書により請求行為を行う』流れになります。 ただ、売上と請求だけで考えれば機能要件を満たす段階であれば前者のレベルで実装して問題は無いのですが、後者レベルを理解せずに前者レベルでの理解力しかない場合、簡易実装したが為の社内締(会計上の締)と社外締(取引契約上の締)で起きる矛盾に適切な対処判断する事が出来無いと考えます。 つまり「関連クラス」は実装工程では無く、分析/設計工程の為の物では無いでしょうか? | ||||
|
投稿日時: 2004-12-28 02:49
そもそも関連クラス/関連型の特長は、二つのオブジェクトを結ぶ多対多の関連について、それぞれのインスタンスを一つに絞れる制約がある事だと、とM.ファウラー師とかC.ラーマン師とかが言ってたような。
概念モデルでしか使わないモノのようなのであまり親しみはないけれど。実装では属性か普通のクラスか何かになっちゃうでしょう。 # 関連クラスをそのまま実装できるOOPLってあるの? | ||||
|
投稿日時: 2004-12-28 10:30
そうですね。 私の知識範囲では、 関連クラスで表現出来るほどの意義のある関連を簡略化する場合は、俗に言われる「制御情報」に変わります。この制御情報を「ビット」「処理日」「処理連番」「関連制約の条件となる属性の保持」のいずれか、またはその複合で表しますが、その判断をする際は関連の理解度とシステム方針(要件)の両者に大きく左右されると考えています。 [ メッセージ編集済み 編集者: はにまる 編集日時 2004-12-28 10:32 ] | ||||
|
投稿日時: 2004-12-29 13:27
はにまるさんの書き込み (2004-12-28 02:02) より:
>この際、実装対象外に決断したからと言って、一旦認識した事を分析行為や設 >計行為の記録から抹消する事はありえず。それより存在を認識し如何いう機構 >か理解した上で対象外の決断を行った事を記録する事が非常に重要になります それはつまり、「関連クラスも、どーせ実装には使わないが、設計までなら使うかな」 という感じでしょうか? まあそれはそれなんですが、 たとえ実装に落ちないものだとしても、 (というかむしろ、上流で使うならば尚更思うんですが、) 「作りたい構造を、そのまま」 表現できて欲しいと思います。 実装ならばそれこそ実装しやすいように妥協することが多いんですが、 上流ならば、実装言語とかのつまらない制約(^^;をとりあえず脇に置いといて、 こうしたいんだ!ってのを記述したいものです。 で、「これ本当は関連であり且つクラスにしたいんだけどな」という要望を持っていて、 且つ「多重も許したいんだけどな」という要望も持っているとき、 UMLではそれを表記できない、ということになってしまうと、 設計レベルでもそれを表記できないわけですから、 結局設計レベルでも「UMLの関連クラス」は役立たないんです。 | ||||
|
投稿日時: 2004-12-29 16:31
objectです。
>guionさん >UMLが言語(プログラム言語に近い奴…形式言語とかいうんでしたでしょうか?)である以上、 >「形式的」であることは、歓迎されることであろうと思います。 私が「形式的(表面的)」と書いたのはそういう意味ではありません。 細かい説明をしていませんが、 今の「UML」の枠組みでは、「広義の関連クラス」と「普通のクラス」を区別する事は出来ません。 詰まり、 「狭義の関連クラス」を「関連クラス」と呼称する事で、合理的にはなっている 訳です。 しかし、それでは 「クラス」に止揚された「関連」は一体何だったの? という意味で、「形式的(表面的)」という言葉を使わせて頂きました。 別の表現をすれば、 「広義・狭義の関連クラス」を導入する為には、 「今の枠組み」とは異なる「別の枠組み」を採用 しないと、或る意味で言葉に矛盾(曖昧性)が生じるのではないでしょうか? 私は、それが出来ないから現状維持をせざるを得ないと考えています。 それから、私の 「そこまで有効に実現しよう」とはしていない に関しては、 上の説明を踏まえて、理解して下さい。 >あと、UMLについて言えば、普通(?)のプログラム言語と違って、 >見た目つまり直感に訴える部分とも >出来るだけ矛盾しないように作ったほうが >「もっと役立つ」という側面もあります。 > >なので、先ほども書きましたが、メタレベル(つまりルール)をユーザが変更できるというなら、 >メタレベルの絵をユーザがさくさく作れないと「使い物にならない」のだと思います。 仰りたい内容には、或る程度私も同意します。 しかし、その為には 「UML」に於いて、 「構造的にシッカリした枠組みが必要・十分な形で整理」 されないと、無理なのではないでしょうか? 「UML」は、まだそこまで至っていないと私は思っています。 >判り易くしたというよりも、「筆者による関連クラスの理解」が >あの文章には表れているんだと想像しています。 >つまり、(あの筆者じゃなく)私が先に指摘したような「誤解」を、 >正に筆者はしている真っ最中なのではないか?と。 >‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥‥ >その間だいたい3ヶ月。その間ずっと筆者氏は誤解し続けてるのではないか?と想像しています。 かなり厳しいですね。 これに関しては、読者サイドの想像ではなく、筆者御自身が何らかの形で対応して頂ける事を祈ります。 >ただ、その割には、Javaと随分違うところも多いですね。 >一体どういう位置付けを目指してるのか、正直、よく判らないです。 これは、「Java」と全く同じという意味ではなく、 「Java」以外の例えば、「C#」に近い内容での議論等を殆ど聞かない と言う主旨での 「UML」が少し言語に近過ぎるのでは? という意味で書きました。 >たとえば、「関連はデフォでは両方向だ」っていう辺り。 >実装言語ではそんな言語は希少ですし、 >概念的にも、両方向も片方向も別にどっちを主にしても良さそう。 >なのに、わざわざ両方向を選んだわけで… ここに関しては、少し私とは意見が違う様です。 「UML仕様書」での「関連」の説明を抜粋します。 -------------------------------------------- 関連(Association):関連は分類子間の意味的な関係を定義する。 関連のインスタンスは、分類子のインスタンスに関係するタプルの集合とする。 各タプルの値は、多くとも一度しか出現しない。 メタモデルでは、Associationは、ClassなどのClassifier間の意味的関係の宣言である。 Associationは、少なくとも2つのAssociationEnd(関連端)を持つ。 各端点は、1つのClassifierに結ばれる。 同じAssociation内の複数のAssociationEndが同一のClassifierに結ばれてもよい。 Associationは、Classifierのインスタンス間の接続集合を表す。 Associationのインスタンスは、Link(リンク)、すなわち、対応するClassifierから導かれたInstance(インスタンス)のタプルとなる。 -------------------------------------------- >ああ。クラス図の二段目と三段目の合体技ですね(^^; >今のUMLじゃ素直に描けないですね。 > >私はVB/Delphiあがりなんで、 >属性とメソッドみたいな低級概念だけをサポートしてて、 >その上のプロパティをサポートしてないってのは、 >すごく奇異に感じました。 私は、もっと基本的な意味で書きました。 #プロパティに関する私の考えは、要約を以下のスレに簡単に書きました。 #良かったら参考にして下さい。 #件名:.NET開発者のためのリファクタリング入門について 私はベースは「C++」ですが、「Delphi」で「コンポーネント指向」は学ばさせて頂きました。 | ||||
|
投稿日時: 2004-12-29 17:01
本当に? あなたの主観だけではなくて? | ||||
|
投稿日時: 2004-12-30 14:31
objectです。
>はにまるさん >つまり「関連クラス」は実装工程では無く、分析/設計工程の為の物では無いでしょうか? 1つだけお聞きします。 それでは、「分析/設計工程」は何の為にあるんでしょうか? | ||||
|
投稿日時: 2004-12-31 10:00
未記人さんの書き込み (2004-12-28 02:49) より:
>そもそも関連クラス/関連型の特長は、二つのオブジェクトを結ぶ多対多の関 >連について、それぞれのインスタンスを一つに絞れる制約がある事だと、とM. >ファウラー師とかC.ラーマン師とかが言ってたような。 うーん。 まあ最悪、現状の「純関連クラス」をそのままにしておくとしても、 それとは別の問題として、「広義の関連クラス」のほうの生きる場所もUML上に存在して欲しいですね。 今のままだと、「広義の関連クラス」には、 通常クラスと通常の関連の仕組みを間借りする、難民のような立場(^^;しか与えられていません。 このままでは、そこが関連なんだよ!ということが「見づらい」。 ところで「UMLモデリングの本質」(児玉公信氏)のP46あたりにちょうど、 関連クラスの描き方の話題が挙がっています。 図2-5はUMLの純関連クラスを使う場合。(よって多重を許さない) 図2-6は通常のクラスを使って広義関連クラスを(も)表現する場合。(多重を許す) 図2-5 学生(*)---(*)科目 | \---履修 図2-6 学生(1)---(*)履修(*)---(1)科目 ちなみにその例では、Nodeが「学生」と「授業科目」、関連クラスが「履修する」です。 で、図2-6では、図2-5で表現できない「最履修」が表現できています(^^; 図2-6のように通常クラスと通常関連を「流用」して広義関連クラスを作ると、 たとえば関連の多重度の組み合わせに独特のイディオムが発生する (Node側の多重度が必ず1になる) などといった「お約束」が出現します。 こういったお約束が有るってことは、逆にいえば、 お約束を全部満たして初めて、それは(広義)関連クラスだと安心して呼べる代物になる ということを意味します。 これは、「ここんとこは関連(クラス)なんだよ!」ということを言いたいという作者の意図を、 簡潔に表現できない ということになるんじゃないでしょうか? そういうお約束を、簡単な絵を描くだけで自動的に解決してくれるのが、 図言語の旨みだと思うのですが…? 現状だと、なんていうか、UMLの実装:-)の都合にあわせて、 ループやサブルーチンをべた書き展開しちゃったみたいな感じ。 なお、上記モデルは本当は、 「科目」を「科目そのもの」と「開講単位」とに分割するほうが良い、 のかも知れません。そうすれば多重関連の問題を「回避」できますし。 が、そういう「モデルの巧拙」の問題は、とりあえず置いておくほうがいいでしょう。 美文しか書けない文法ってのは、ちと病的です。 >概念モデルでしか使わないモノのようなのであまり親しみはないけれど。実装 >では属性か普通のクラスか何かになっちゃうでしょう。 ># 関連クラスをそのまま実装できるOOPLってあるの? 一応、私が扱ってる(どマイナーな)システムには、有ります(^^; なおこれは前述のとおりUMLと無関係に作られたものなので、 ここで言う「関連クラス」はUML流の「純関連クラス」ではありませんが、 いずれにせよ、そのぶん「使いやすい」です。 まあこれも訓練だと思います(^^; 分析設計はもとより、実装にいたるまで、長年この関連クラスに慣れ親しんでいれば、 スムーズに使えるようになります。 つまり慣れれば「どういう場面で使うの?使いどころなんて有るの?」という疑問は解消します。 まあこんな感じです。 (以下、擬似言語ですのでご了承を。JavaとかRubyとかそれ以外とか混ぜこぜ。) まず大もとのシステムには以下のクラスが最初から有ります。 class Object{} class Node extends Object{} class Relation extends Object{ Node left, right; } 抽象クラスRelationは、具体性を持たない中立な立場なので、 接続する2つのNodeへの参照を、leftとかrightとかいう 特に"意味のない"名称で呼んでいます。 次に、例えば上記の例を実装してみるならば、こんなとこ。 class 学生 extends Node{} class 科目 extends Node{} class 履修 extends Relation, left=学生, right=科目, left_to_right=履修する, right_to_left=履修させる {} Relationクラスの定義の仕方については、上記のように拡張されています。 まず、leftとrightに繋がるNodeのクラスが それぞれ何であるか?を、上記みたいにしてクラス定義の段階で指定できます。 また、Relationを辿る(後述)とき、左右どっち向きに辿りたいのか?を指示するためのキーワードを 指定(作成)することになってまして、このキーワードはクラス名とかと同様にシステム全体で重複不可です。 (つまりキーワードを指定すれば、関連クラスおよび「どっちに辿りたいか」を一発で一意に指定したことになります。) 次に上記クラスを使うときは、単(?)に、 学生1 = 学生.new 科目1 = 科目.new 履修1 = 履修.new(学生1, 科目1) //こういうコンストラクタを定義しておいた、という前提で。 とやるだけです。 また多重化も許されていますから、 上の処理に続けて(つまり履修1が存続したままで)以下のようにしてもエラーにはなりません。 最履修1 = 履修.new(学生1, 科目1) 作ったオブジェクトの使い方は、前述のように参照関係を検索するシステムが内部にあるおかげで、 逆参照は必要なときに勝手に辿ってくれますから、単に、 学生1_履修関係_ary = 学生1.getRelation(履修する) というように、片方のNodeに対してRelationを辿るメソッドを (上記のキーワードを引数として)呼べば、 学生1_履修関係_ary.each{|a| puts a.node puts a.relation } # => "科目1" # => "履修1" # => "科目1" # => "再履修1" なんてな風になります。 で、上記のデータ例だと、同じ「科目1」(への参照)が二度出てくるわけです。 なお、コンストラクタを適切に改造(Override)することにより、 最履修のような多重化を認めないRelationクラス、も簡単に作れます。 多重化してしまうならば例外を投げるように実装すればいいのです。 つまり選択肢は有り、必要に応じて幾らでも行使できます。 |