UML におけるクラスとオブジェクトの中間点はどこにあるのでしょうか?

StackOverflow https://stackoverflow.com/questions/878863

質問

を図示したいとします。 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 クラス。大丈夫。ここで、次から構成された (1:2) の線を描画します。 MapSet -- それぞれ 1 つ @nodes そして @edges. 。次に、 has-many(1:0..*) 行 SetNode そしてもう一つから SetEdge. 。しかし今私が言いたいのは、各セットには以下を任意に組み合わせることができるということです。 NodeEdges、それは真実ではありません。そして、2つを置くのは役に立ちません Set これらは同じオブジェクトであるため、図上の要素 (対応する 2 つの Compused-Of(1:1) 行を含む)。

ので、私は考えました:そうですね、UML は私にもっと C++/Java っぽくなってほしいと思っているのかもしれません。テンプレート化された Set<Node> そして Set<Edge> UML では不可能ですが、サブクラスを作成することはできます。 NodeSet そして EdgeSet.

最後にオブジェクト図を考えましたが、それは正しくありません。私が話しているのは、 Set 個人ではなくクラス Set インスタンス。

もっと良い答えはあるでしょうか?それとも、「最も悪い」ものをすでに見つけましたか?

後で

という答えが マーク・W そして ピート・カーカム 私が最初に述べたように、質問としては素晴らしいです。問題は、実際の問題をそのまま明らかにすることができないため、実際の問題に単純な類似点を使用しようとしていたことです。私は実際には、異なる関係を持つ同じクラスの 2 つをどのようにして同じように動作し、同じ属性 (ただし属性値ではない) を持つようにするかについて少しだけ知りたかったのです。

いくつかの異なるモデルでもう一度試してみましょう。の ActiveDirectory, 、 Firewall, 、そして2つ Routers.1 つのルーター (LAN ルーター) には、 ActiveDirectory そしてその Firewall;もう一方 (WAN 側) には、 Firewall そしていくつかのパブリック サーバー (この図では無視します)。両方とも十分に考えられます Routerメーカー、モデルなどが同じです。シリアル番号は異なりますが(オブジェクトは異なります)、間違いなく両方です Routers.両方をクラス図に配置するには、サブクラス化する必要があります Router の中へ LANRouter そして WANRouter. 。Marc W のソリューションに似ているのは、 Firewall そして ActiveDirectory 実装はそのままにして直接(Router) を決定するクラスに追加します。ただし、UML を使用して実際にシステムを構築する場合は、抽象化がリークする必要があります。

役に立ちましたか?

解決

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

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

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

その情報が役立つ場合は、Map をドメイン モデルのパラメトリック タイプにするとよいでしょう。ただし、その情報は実装では使用されないため、要点を理解するのが少し難しく、実用性を失わずに物事をできるだけ単純にすることがモデリングの常に目標となります。

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

他のヒント

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top