2

Mapクラス (地図作成の種類ではなく、数学の種類)を図で示したいとしましょう。Ruby では、次のようなものがあります。

class Map
  attr_accessor :nodes, :edges
  def initialize
    @nodes = Set.new
    @edges = Set.new
  end
  def minimum_spanning_tree(&mst_algorithm)
    mst_algorithm.call(@nodes, @edges)
  end
  ...
end

これを図式化し始めると、私の考えは次のようになります。

クラスについて話しているので、クラス図を試してみましょう。クラスを作りますMap。そしてNodeクラス。そしてEdgeクラス。そしてSetクラス。罰金。次に、 Composed-Of(1:2) 行をMapto からSet-- と ごとに 1 つずつ@nodes描画します@edges。次に、 to からの has-many(1:0..*) 行とSettoからNodeの別の行。しかし今、私は各セットが と を任意に組み合わせて使用​​できると言っていますが、これは正しくありません。また、図に 2 つの要素 (対応する 2 つの Composed-Of(1:1) 行) を配置しても、それらは同じオブジェクトであるため役に立ちません。SetEdgeNodeEdgeSet

だから私は考えました:まあ、UMLは私がもっとC++ / Java風になることを望んでいるのかもしれません。テンプレート化されたSet<Node>Set<Edge>は UML では使用できませんが、サブクラスを作成できました:NodeSetEdgeSet.

最後にオブジェクト図について考えましたが、そうではありません。個々のインスタンスSetではなく、クラスについて話しています。Set

より良い答えはありますか?または、「最も悪い」ものをすでに見つけましたか?

後で

マーク Wピート カーカムの答えは、私が最初に述べた質問に対する素晴らしいものです。問題は、存在する問題を明らかにすることができないため、実際の問題に単純な類推を使用しようとしていたことです。私は実際には、異なる関係を持つ同じクラスの 2 つを持つ方法について少し調べただけでしたが、同じように振る舞い、同じ属性 (属性値ではありません) を持っています。

いくつかの異なるモデルでもう一度試してみましょう: an ActiveDirectory、 a Firewall、および two Router。1 つのルータ(LAN のもの)には、 および への参照がActiveDirectoryありFirewallます。もう一方 (WAN のサーバー) には、Firewallおよびいくつかのパブリック サーバーへの参照があります (この図では無視します)。Router両方の が同じ製造元、モデルなどであることが完全に考えられます。シリアル番号は異なりますが (オブジェクトは異なります)、間違いなく両方とも ですRouter。両方をクラス図に入れるには、 と にサブクラスRouter化する必要がLANRouterありWANRouterます。Marc W のソリューションとの類推は、Firewalland をActiveDirectory直接接続し、実装を残すことです (Router) 決定するクラスに。しかし、UML を使用して実際にシステムを構築する場合は、抽象化が漏れる必要があります。

4

2 に答える 2

3

実装ではなくドメインをモデル化している場合、UML は関係のステレオタイプを提供します。この場合、ノードとエッジを、バッグまたはセットに関連する {unordered} としてマークし、それを Set に絞り込む {unique} としてマークします。ノードまたはエッジのタイプに制限が見当たらないので、存在しない場合は追加しないでください。

class Map
  +nodes : { unordered, unique } object[0..*]
  +edges : { unordered, unique } object[0..*]
  +minimum_spanning_tree(mst_algorithm:callable)

優れたコード ジェネレーター/リバース エンジニアリング ツールは、ソース コード内の Set との間で { unordered, unique } UML コレクションをマップします。

その情報が役立つ場合は、ドメイン モデルで Map をパラメトリック型にすることをお勧めします。しかし、情報は実装で使用されないため、ポイントがわかりにくく、実用性を失うことなく物事をできるだけ単純にすることは、常にモデリングの目標です。

特定のクラスがセットを使用して実装されていることを文書化したい場合は、関連付けを使用してそれを行うことができます。C++ または Java で Set 内の要素の型を宣言できること、およびこれらが UML のパラメトリック型にマップされることは正しいです。私の知る限り、Ruby にはそのような型制限を実装するメカニズムがないため、Map の Ruby 実装を文書化するには、実装にあるものだけを文書化します。Map には Set への 2 つの関連付けがあり、Set にあるものに制限はありません。(これを型制約ではなく、不変制約として文書化し、それを単体テストすることもできますが、制限的な静的型チェックが必要な場合、Ruby で作業する理由を理解するのは少し難しいです)。

于 2009-05-18T18:07:11.410 に答える
2

Mapからまで線を引かないでくださいSet。この場合、Setは本当に重要なオブジェクトを保持する Ruby によって与えられた単なるデータ構造です。それが a Set、 a HashMap、 anArrayなどであるかどうかは実装固有であり、UML には関係ありません。Composed-of(1:0..*) 行 from MaptoNodeおよび from Mapto を作成するだけEdgeです。結局のところ、英語では、あなたMapは本当にノードとエッジで構成されていますよね? 図に含める理由はMap、実際にクラスを作成するのはあなただからです。

オブジェクト図についてはその通りです。この場合は必要ありません。あなたが提案したテンプレート構文と同じです。

于 2009-05-18T17:34:33.207 に答える