Let's say you want to diagram a Map
class (the mathematical kind, not the cartographic kind). In Ruby, you might have something like:
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
When I start diagramming this, my thinking goes as follows:
Let's try a Class diagram since we're talking about classes. I'll create a Map
class. And a Node
class. And an Edge
class. And a Set
class. Fine. Now I'll draw a Composed-Of(1:2) line from Map
to Set
-- one for each @nodes
and @edges
. Then a has-many(1:0..*) line from Set
to Node
and another one from Set
to Edge
. But now I'm saying that each set can have any mix of Node
s and Edge
s, which isn't true. And it doesn't help to put down two Set
elements on the diagram (with two corresponding Composed-Of(1:1) lines), since they're the same object.
So I thought: well, maybe UML wants me to be more C++/Java-ey. A templated Set<Node>
and Set<Edge>
aren't possible in UML, but I could create subclasses: NodeSet
and EdgeSet
.
Lastly I considered an Object diagram, but that's not right. I'm talking about the Set
class, not individual Set
instances.
Is there a better answer? Or have I already found the "least bad" one?
Later
The answers that Marc W and Pete Kirkham are fantastic for the question as I first worded it. The problem is that I was trying do use a simple analogy to my real problem because I can't reveal the problem as it exists. I was really only after the bit about how to have two of the same class that have different relationships, but act the same and have the same attributes (though not attribute values).
Let's try again with some different models: an ActiveDirectory
, a Firewall
, and two Router
s. One router (the LAN one) has references to the ActiveDirectory
and the Firewall
; the other (the WAN one) has references to the Firewall
and some number of public servers (we'll ignore them in this diagram). It's perfectly conceivable that both Router
s are of the same make, model, &c. They'll have different serial numbers (the objects are different), but they're definitely both Router
s. Yet to put both on a class diagram, I have to subclass Router
into LANRouter
and WANRouter
. The analogy to Marc W's solution is to connect the Firewall
and ActiveDirectory
directly, leaving the implementation (Router
) to the class to determine. But the abstraction must leak if the UML is to be used to actually build the system.