Is there some way to avoid duplication of the edges in Roasal? I'm building a diagram of the meta-model form Moose, and I have some opposite relations but I don't have a reason to show them in both directions.
Related
Please Look at the following example:
1) The chairs are made of wood .
2) Paper is made from trees .
3) Biogas is produced by the fermentation of waste.
4) Asphalt is produced through the refining of petroleum.
Should these be Composition or Dependency?
In general
You can exclude UML composition: composition implies an exclusive ownership. But chairs are not the only products made of wood.
Dependency is either too much (once the biogas is made, there is no dependency to waste anymore) or not enough (the wood of the chair is part of the chair; it's a stronger relationship than a need-to-know-about).
Moreover it is not clear if you want the Chair to be a class on its own or an instance of a class product.
Specific cases
"Made of" expresses a relationship with parts that make a product. A typical pattern here is the bill of material. The relation is a simple association. Some people tend to use UML aggregation, but UML specifications do not define precisely the semantics, so leave it out to avoid ambiguity.
Here a (very simplified) diagram:
"Made from" expresses a transformation process, where some of the original products disappear in the process and others are created. Paper is made from cellulose which is extracted from trees. But the original tree is not in the sheet of paper.
Typically in process industries, like chemicals, this is represented by a "recipe", which is a sequence of inputs (waste) and operation to obtain products (biogas) and co-products (fermented residual waste). In other industries, this is represented by a "routing" that is a sequence of operations performed on a BOM (in this case, the BOM would not only contain components as previously shown, but also raw products that are transformed by the operations in the routing).
I will not show a diagram because this is quickly very complex, but again, it'll use simple associations.
In the end, "made of" and "made from" would both be represented in UML with associations. But only the semantic that you attach to it will change.
I don't think that any "made of" is represented by some static relation. To make a wooden chair it just Depends on wood. There is no other relation here because you have some complicated process to turn wood into a chair. Or a tree into paper. Or anything else of your choices. In order to describe the relation you would need to describe the process. This is possible using activities. You could as well descibe physical components with UML. But that would take us too far apart from your question...
You might search for answers on composition here. But even these can be looked at controversial. Modeling reality yields a model. Which is not reality.
Your question highlights the difference between an ontology and an information model or application design. For example, in a conceptual ontology (which accounts for necessary and possible situations in the world rather than for data formats of observations and measurements), every person has a mother. In a particular database or application, that knowledge is usually irrelevant. What stuff is made of and how it is produced belongs more to a conceptual ontology, for which UML is not quite expressive enough. This is why languages such as First Order Logic (FOL) and OWL are used instead, and why some tools (such as my company’s) plug holes in UML. (One example of a hole in UML is the inability to express exactly the intersection of two classes.)
I'm trying to create a class diagram for a node-edge relationship, as it would be found in a directed graph. I want to convey that Nodes have references to Edges, and Edges also have references to Nodes.
Every Edge needs exactly two Nodes (source and target).
Would this be an acceptable way to model this?
Yes, this diagram expresses perfectly what you describe in the text. The doubled association is right: each association expresses something different.
You are somewhat more precise in the diagram than in the text, since you show that each node has inEdges and outEdges, whereas the text just mentions the reference to Edges without being more explicit.
A common variant for the implementation of directed graph is that the Node knows only its outEdges. If this is important, you may express it with navigability, with an arrow in direction of sourceNode and a cross on the side of inEdges. But this practice is relatively rare in the model.
For an undirected graph, you could have only one association with a multiplicity of 2 on the side of the nodes.
I have a short question:
Should I name attributes of types like a List, Arrays, Vectors or Pointers to objects (not primitive type) in the UML diagram or the only association/aggregation/composition arrows are enough?
Example: which of these diagrams is correct?
or
In UML, your second diagram would be correct if you wrote the property names at the far ends of the associations. While UML properties are allowed to be unnamed, it is not a good practice. Use association ends to indicate why the relationship exists. Sometimes more than one association must exist between one pair of classes, but for different reasons. How would you tell them apart?
The first diagram shows two properties of each type. One is named and another (at the end of each association) is unnamed. That is incorrect.
This really depends on what you're trying to convey in this architectural drawing.
The purpose of the drawing is to help reason about the structure of the software. It should not be used to represent all of the details of implementation. If you put too much detail in it, it becomes cluttered, and it is hard to keep it consistent with the source code as changes occur.
The UML drawing should be more abstract than the implementation. It should hide details on purpose, so that it conveys the external view of classes, and not how they are implemented internally. You generally don't want users of classes to assume too much about their internal implementation, therefore you don't want to expose it too much.
Also, an architecture is typically represented by several drawings - not one. Try to have each drawing focus on one level of abstraction. If you have a few high level classes that represent the main logic of the application, and many low level classes, it makes sense to have a drawing of just the high level classes separately.
I'm writing a graphical editor for a "model" (i.e. a collection of boxes and lines with some kind of semantics, such as UML, the details of which don't matter here). So I want to have a data structure representing the model, and a diagram where an edit to the diagram causes a corresponding change in the model. So if, for instance, a model element has some text in an attribute, and I edit the text in the diagram, I want the model element to be updated.
The model will probably be represented as a tree, but I want to have the diagram editor know as little about the model representation as possible. (I'm using the diagrams framework, so associating arbitrary information with a graphical element is easy). There will probably be a "model" class to encode the interface, if I can just figure out what that should be.
If I were doing this in an imperative language it would be straightforward: I'd just have a reference from the graphical element in the diagram back to the model element. In theory I could still do this by building up the model from a massive collection of IORefs, but that would be writing a Java program in Haskell.
Clearly, each graphical element is going to have some kind of cookie associated with it that will enable the model update to happen. One simple answer would be to give each model element a unique identifier and store the model in a Data.Map lookup table. But that requires significant bookkeeping to ensure that no two model elements get the same identifier. It also strikes me as a "stringly typed" solution; you have to handle cases where an object is deleted but there is a dangling reference to it elsewhere, and its difficult to say anything about the internal structure of the model in your types.
On the other hand Oleg's writings about zippers with multiple holes and cursors with clear transactional sharing sounds like a better option, if only I could understand it. I get the basic idea of list and tree zippers and the differentiation of a data structure. Would it be possible for every element in a diagram to hold a cursor into a zipper of the model? So that if a change is made it can then be committed to all the other cursors? Including tree operations (such as moving a subtree from one place to another)?
It would particularly help me at this point if there was some kind of tutorial on delimited continuations, and an explanation of how they make Oleg's multi-cursor zippers work, that is a bit less steep than Oleg's postings?
I think you're currently working from a design in which each node in the model tree is represented by a separate graphical widget, and each of these widgets may update the model independently. If so, I don't believe that a multi-hole zipper will be very practical. The problem is that the complexity of the zipper grows quickly with the number of holes you wish to support. As you get much beyond 2 terms, the size of the zipper will get quite large. From a differentiation point of view, a 2-hole zipper is a zipper over 1-hole zippers, so the complexity grows by operation of the chain rule.
Instead, you can borrow an idea from MVC. Each node is still associated with a widget, but they don't communicate directly. Rather they go through an intermediary controller, which maintains a single zipper. When widgets are updated, they notify the controller, which serializes all updates and modifies the zipper accordingly.
The widgets will still need some sort of identifier to reference model nodes. I've found it's often easiest to use the node's path, e.g. [0] for the root, [1,0] for the root's second child, etc. This has a few advantages. It's easy to determine the node a path refers to, and it's also easy for a zipper to calculate the shortest path from the current location to a given node. For a tree structure, they're also unique up to deletion and reinsertion. Even that isn't usually a problem because, when the controller is notified that nodes should be deleted, it can delete the corresponding widgets and disregard any associated updates. As long as the widget lifetime is tied to each node's lifetime, the path will be sufficiently unique to identify any modifications.
For tree operations, I would probably destroy then recreate graphical widgets.
As an example, I have some code which does this sort of thing. In this model there aren't separate widgets for each node, rather I render everything using diagrams then query the diagram based on the click position to get the path into the data model. It's far from complete, and I haven't looked at it for a while, so it might not build, but the code may give you some ideas.
I'm reading the book on Domain Driven Design of Eric Evans - Chapter 5, concerning associations. One of his advices to reduce complexity of a model is to impose a traversal direction for the associations.
I quote:
It is important to constrain relationships as much as possible. A
bidirectional association means that both objects can be understood
only together. When application requirements do not call for traversal
in both directions, adding a traversal direction reduces
interdependence and simplifies the design. Understanding the domain
may reveal a natural directional bias.
How to chose a traversal direction for an association? Generally, when there is an association between two elements, it may be read and understood in the two directions. What may cause us to chose one direction over the other?
Thanks
When there's an association between entity A and entity B, you'll often find yourself using only A.B and never B.A. This may be because A is an aggregate root and is always your starting point, because you already have a reference to its A wherever you manipulate a B, etc.
I guess Evans simply suggests that you should add a traversal direction only when you need it and will use it in the code just after, as opposed to prematurely adding a traversal direction "in case we need it later".
Conceptually all associations are bidirectional. Nevertheless, when implementing them most end up being unidirectional since then you just need to maintain the links in one of the participants.
During design you may want to indicate the navegability to break the bidirectionality at the implementation level and facilitate the coding of the system