I have to model a situation where I would like to use specializations to ensure classes are somewhat normalized, but:
Risk multiple inheritance problems, especially in the long run
Will need to derive an XML-compliant UML model from it (a.o., only one superclass allowed)
The simplified situation is as follows (see also diagram below): we have Parts, like doors, bolts, wheels, etc., and Tools, like drills, ladders, and bigger machinery. All of these may be used in generic processes, like Orders, Shipments, etc. As such, I would like to have one superclass (Powertype, maybe?) that represents them, say Item.
Both Tools and Parts have specialized classes that carry a serial number. As such, I figured that a SerializedItem class with a SerialNumber, which both SerializedPart and SerializedTool inherit, would ensure that all serialized 'things' we have carry at least the same information. However, I also need these Serialized items to carry at least the same information as their more generic parts, and hence I would introduce multiple inheritance.
I have considered making the Item classes interfaces. This would at least mitigate some (many, all?) multiple inheritance problems. This is where another however comes in: aside from an attribute SerialNumber, I would also like to enforce that all Serialized specializations have an aggregation relation with a Manufacturer. Aggregation to an interface is not allowed, so I feel like I cannot with one relation to the superclass enforce this relation.
As such, I have the following considerations/problems:
Have two disjoint 'branches' of Item, with little to no technical governance on content of Serialized specializations
Item classes as Interfaces, but then little governance w.r.t. use of Manufacturer by Serialized specializations
All concrete classes, but then there exist multiple inheritance issues which must be solved when trying to derive XML classes from the model
Which option would you prefer, and why? Did I miss any considerations?
If you want to have a (platform-independent) information design model (similar in spirit to a conceptual model), then you should use multiple-inheritance if this reflects the concepts of your problem domain.
According to such a model-based engineering approach, your model is a pretty good design model that can be used as a basis for making (platform-specific) implementation models such as, e.g., a Java class model or an XML Schema model.
For making an XML Schema model, you would have to choose a certain mapping. In particular, you need to choose a mapping for resolving the multiple inheritance pattern, see also https://stackoverflow.com/a/27102169/2795909.
I just would not make SerializedItem a superclass. Nothing is a serialized thing which generalization would mean. Things can conform to a serialization protocol which is the same as implementing an interface (maybe called Serializable). If you happen to deal with serializable things without bothering about their content you would just deal with Serializable and only know the number.
Basically you should make your SerializedItem an interface (eventually renaming it to Serializable), remove the generalization upwards and make the two horizontal ones realizations.
This is probably not an ultima ratio. But to me this approach sounds more reasonable.
Related
I am currently making a domain model of a combat game, and I have difficulties determining whether certain elements should be a class of their own or attributes of some class. For example, I have used a category list to determine the following ideas/objects: Fighter, Level, Weapon, Armor, Attributes, Skills, Arena, Game Mode, Game Log, Opponent.
For example, I can't tell whether Level, Weapon, Armor, Attributes, Skills should be simply stated as attributes of a fighter or should they be delimited as their own object. I can't tell either if an opponent should be a distinct class since it is ultimately a fighter object with an 'attack/defend' association to another fighter.
How does one determine what would be the correct choice for each element in a category list? Can these be subjective?
FYI, I am using Craig Larman's "Applying UML and Patterns" 3rd Edition as an information source.
To clarify your question for a moment -- each Class in your domain model will have a set of Attributes. The question I think you are asking is whether the Type of each of these Attributes should be a Class themselves, or some other data structure (e.g. a struct, enum, primitive etc.)
If this is correct, then the answer comes down to design choices that stem from your analysis; there is no one 'correct way' -- this is the art of software design. There are however a few key things you might want to look for in making your decision:
Evidence of behavioural requirements. Does the object that an Attribute refers to need to encapsulate behaviour itself? Clearly it's impossible for certain data structures to encapsulate behaviour, which may lead you to make choices towards those that can (e.g. a class vs a struct).
Complexity of data structure. Does the object that the Attribute refers to need to encapsulate complex data structures? (e.g. multiple, possibly hierarchical, data of various primitives and/or complex types) Or is it simple? (e.g. a single integer value). Again, complexity in structure will limit how you can represent it.
What are the non-functional requirements of your system? (e.g. performance requirements?) NFRs like performance, scalability and security may constrain your design choices, so that you might choose to represent complex types in simple ways or eliminate behavioural needs etc..
Does the design choice help you or hinder you? There's no point in representing something in an overly complex way that hinders your work or the system.
Audience. This is possibly the most important point -- who are you putting the domain model together for, and what are you trying to communicate to them?
So, for example, you could represent "Weapon" as an attribute typed as a class or using a simple type. Does "Weapon" have behaviour of its own? Does it contain multiple complex data? Is there a NFR that means it can only really be treated as an enum? And so on.
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.
What is the best way to represent a "mixin" using UML?
As documented in this article:
In object-oriented programming languages, a mixin refers to a defined
amount of functionality which can be added to a class. An important
aspect of this is that it makes it possible to concentrate more on the
properties of a particular behaviour than on the inheritance
structures during development.
I will give more details about my particular use case.
I have a collection of classes that model different types of objects. Because all of them can be stored on a storage, I want to use a mixin to implement all the functionality related to "being stored".
Of course, I can use abstract classes but I do not like it because these classes should be part of a different hierarchy of classes and the fact that they can be stored is only a secondary property.
Another option can be to use composition and add the "storage node" as a field of this classes. I do not like this option either for the same reason: I do not want to create any dependency between the classes and the storage.
I have already implemented the solution in Java using a mixin based on dynamic proxies and I would like to document the solution with a clear UML class diagram. Is there a standard way to represent this mixin?
I am also wondering whether it is a good idea to model also how the mixin has been implemented (using proxies) or it is better to use a more abstract representation.
Thanks
Actually there are many ways to model this in UML:
One approach could be to stereotype the operations and properties with <<mixin>> or the like and then use tagged values to describe where you got them from.
Another (I'd prefer) is to actually use a <<mixin>> stereotyped Generalization and attach a note to that telling which operations/properties should be mixed. That would give the implementer a guide to just "lean implementation of the general class".
Eventually you could create <<mixin>> sub-classes with subsets of the ops/props you want to mix in the final class and then Generalize from those.
Probably one could come up with more solutions. Use an approach which suits you best. There is not generic mixin pattern in UML (to my knowledge).
I drives me crazy how many books contradicts themselves.
Class A {} class B {void UseA(A a)} //some say this is an association,
no reference is held but communication is possible
Class A {} class B {A a;} //some say this is
aggregration, a reference is held
But many say that holding a reference is still just an association and for aggregation they use a list - IMHO this is the same, it it still a reference.
I am very confused, I would like to understand the problem.
E.g. here: http://aviadezra.blogspot.cz/2009/05/uml-association-aggregation-composition.html - what is the difference between Strong Association and Aggregation, in both cases the author uses a field to store the reference..
Another example:
This is said to be Association:
And this is said to be Aggregration:
public class Professor {
// ...
}
public class Department {
private List<Professor> professorList;
// ..
}
Again, what is the difference? It is a reference in both cases
This question has been, and will be, asked many times in many different variants, because many people, including many high-profile developers, are confused about the meaning of these terms, which have been defined in the UML. Since the question has been asked many times, it has also been answered many times. See, e.g. this answer. I'll try to summarize the UML definitions.
An association between two classes is not established via a method parameter, but rather via reference properties (class attributes), the range/type of which are the associated classes. If the type of a method parameter is a class, this does not establish an association, but a dependency relationship.
It's essential to understand the logical concept of associations first, before looking at how they are coded. An association between object types classifies relationships between objects of those types. For instance, the association Committee-has-ClubMember-as-chair, which is visualized as a connection line in the class diagram shown below, may classify the relationships FinanceCommittee-has-PeterMiller-as-chair, RecruitmentCommittee-has-SusanSmith-as-chair and AdvisoryCommittee-has-SarahAnderson-as-chair, where the objects PeterMiller, SusanSmith and SarahAnderson are of type ClubMember, and the objects FinanceCommittee, RecruitmentCommittee and AdvisoryCommittee are of type Committee.
An association is always encoded by means of reference properties, the range/type of which is the associated class. For instance, like so
class Committee { ClubMember chair; String name;}
In the UML, aggregation and composition are defined as special forms of associations with the intended meaning of classifying part-whole-relationships. In the case of aggregation, as opposed to composition, the parts of a whole can be shared with other wholes. This is illustrated in the following example of an aggregation, where a course can belong to many degree programs.
The defining characteristic of a composition is to have exclusive (or non-shareable) parts. A composition may come with a life-cycle dependency between the whole and its parts implying that when a whole is destroyed, all of its parts are destroyed with it. However, this only applies to some cases of composition, and not to others, and it is therefore not a defining characteristic. An example of a composition where the parts (components) can be detached from the whole (composite) and therefore survive its destruction, is the following:
See Superstructures 2.1.1:
An association may represent a composite aggregation (i.e., a whole/part relationship). Only binary associations can be aggregations. Composite aggregation is a strong form of aggregation that requires a part instance be included in at most one composite at a time. If a composite is deleted, all of its parts are normally deleted with it. Note that a part can (where allowed) be removed from a composite before the composite is deleted, and thus not be deleted as part of the composite. Compositions may be linked in a directed acyclic graph with transitive deletion characteristics; that is, deleting an element in one part of the graph will also result in the deletion of all elements of the subgraph below that element. Composition is represented by the isComposite attribute on the part end of the association being set to true.
Navigability means instances participating in links at runtime (instances of an association) can be accessed efficiently from instances participating in links at the other ends of the association. The precise mechanism by which such access is achieved is implementation specific. If an end is not navigable, access from the other ends may or may not be possible, and if it is, it might not be efficient. Note that tools operating on UML models are not prevented from navigating associations from non-navigable ends.
Your above examples are on different abstraction levels. Department/Course are concrete coding classes while Department/Professor are at some abstract business level. Though there is no good source (I know) explaining this fact, composition and aggregation are concepts you will use only on business level and almost never at coding level (exception below). When you are at code level you live much better with Association having role names on both sides. Roles themselves are a different(/redundant!) rendering of properties of a class that refer to the opposite class.
Aggregation as a strong binding between classes is used e.g. in database modeling. Here you can delete a master only if the aggregates have all been deleted previously (or vice vera: deleting the master will force deletion of the aggregates). The aggregate can not live on its own. The composition as in your example is (from my POV) a silly construct as it pretends to be some week aggregation. But that's simply nonsense. Then use an association. Only on a business level you can try to model (e.g.) machine parts as composite. On a concrete level a composition is a useless concept.
tl;dr;
If there is a relation between classes show it as simple association. Adding details like roles will aid when discussing domain details. Use of composition/aggregation is encouraged only when modeling on business level and dis-encouraged on code level.
I've written an article about the differences between UML Association vs Aggregation vs Composition based on the actual UML specification rather then interpretations of book authors.
The primary conclusion being that
In short, the Composition is a type of Association with real constraints and impact on development, whereas the Aggregation is purely a functional indication of the nature of the Association with no technical impact.
Navigability is a completely different property and independent of the AggregationKind.
For one thing, UML is a rich language, meaning there is more than one way to describe the same thing. That's one reason you find different ways described in different books (and conflicting answers on SO).
But a key issue is the huge disconnect between UML and source code. How a specific source code construct is represented in UML, and vice versa, is not part of the UML specification at all. To my knowledge, only one language (Java) has an official UML profile, and that's out of date.
So the representation of specific source-language constructs are left to the tool vendors, and therefore differ. If you intend to generate code from your model, you must follow the vendor's conventions. If, conversely, you wish to generate a model from existing source code, you get a model based on those same conventions. But if you transfer that model to a different tool (which is difficult at the best of times) and generate code out of that, you won't end up with the same code.
In language-and-tool-agnostic mode, my take on which relationships to use in which situations can be found here. One point there worth repeating is that I don't use undirected associations in source-code models, precisely because they have no obvious counterpart in actual code. If in the code class A has a reference to class B, and B also has one to A, then I draw two relationships instead.
Are there any tools out there that let you model how a class (or a class hierarchy) can change at runtime? For example, if I have a given number of mixin classes that will be combined at runtime and I don't know which ones will be combined until the program runs, how do you go about diagramming that type of runtime behavior?
Here's a better example. Let's say that I have a base class called IceCream, and I have over 100 possible flavors that all derive from that one IceCream class. Let's also suppose that any instance of the IceCream class can be combined with another instance of the IceCream class to create a completely unique IceCream type altogether. Given this domain, how do you use a graphical model to actually say that any one of these types can be combined at runtime?
It would be inefficient to model all the possible combinations of IceCream types, given that there can be a virtually infinite number of permuations for these 100 IceCream types. So again, here's the question: Are there any graphical modeling languages that let you specify this sort of behavior?
Your design sounds a little disturbing. If two different ice creams have different behavior, then why is it wrong to model all the possibilities? Where are you loading the behaviors from? It very well could be the case, but if so I'd guess that you want to contain the behavior instead...
If they don't have different behaviors, then all you are talking is a class "IceCream" with a "Flavor" member. Never create a second class when the only difference is data--the code must actually differ in the two cases to warrant different classes.
If I totally missed something I apologize.
Edit: Let me be more specific about "Containing behavior". If each of your ice-cream flavors had a "Taste" (which is code) and the taste is different between Vanilla, Strawberry and Chocolate--then you have 3 "Taste" ice-cream classes that are contained in one "Cone" class.
The Cone class would be what I think you are trying to model as "IceCream". Since the cone contains all three, a "Lick" method can combine those three in any way possible. Either you can lick(bottom), lick(middle) or lick(top), or you can just lick() and allow the lick method to combine all three into a single call (to be more real-code, you might pass a single variable to lick() that would be forwarded to all contained flavors).
I wonder if the personal db approach of Bento or DabbleDB could be relevant for the actual modelling part. Then maybe the Django admin's model introspection for the logic part. Sounds like you want to create an interface to a scripting language. A kind of vpl library. So, a beefed up and more reflective Django admin might be a starting point.
In general, if you want to create UML class diagrams you can exploit Generic Types in UML. Also, there is the concept of Template Parameters in UML.
Have a look at this site: Defining Generics with UML Templates
They use the Eclipse Modeling Framework as a tool.