UML Domain Model : How to distinguish attributes and classes? - uml

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.

Related

Normalization versus multiple inheritance

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.

Designing a class diagram for a domain model

First, don't think i'm trying to get the job done by someone else, but i'm trying to design a class diagram for a domain model and something I do is probably wrong because I'm stuck, so I just want to get hints about what i'm not doing correctly to continue...
For example, the user needs to search products by categories from a product list. Each category may have subcategories which may have subcategories, etc.
The first diagram I made was this (simplified):
The user also needs to get a tree list of categories which have at least one product.
For example, if this is all the categories tree:
Music instruments
Wind
String
Guitars
Violins
Percussion
Books
Comics
Fiction
Romance
I can't return a tree of Category which have at least one product because I would also get all subCategories, but not each sub category has a product associated to it.
I also can't remove items from the Category.subCategories collection to keep only items which have associated products because it would alter the Category entity, which may be shared elsewhere, this is not what I want.
I thought of doing a copy, but than I would get 2 different instances of the same entity in the same context, isn't it a bad thing ?
So I redesigned to this:
Now I don't get a collection of child categories I don't want with each Category, I only know about its parent category, which is ok.
However, this creates a tree of categories which is navigable only from the bottom to the top, it makes no sense for the client of ProductList who will always need a top -> bottom navigation of categories.
As a solution I think of the diagram below, but i'm not sure it is very good because it kinda dupplicates things, also the CategoryTreeItem does not seems very meaningful in the domain language.
What am I doing wrong ?
This is rather an algorithmic question than a model question. Your first approach is totally ok, unless you were silent about constraints. So you can assign a category or a sub-category to any product. If you assign a sub-category, this means as per this model, the product will also have the parent category. To make it clear I would attach a constraint that tells that a product needs to be assigned to the most finest know category grain. E.g. the guitar products would be assigned to the Guitar category. As more strange instrument like the Stick would get the Strings category (which not would mean its a guitar and a violin but just in the higher category.
Now when you will implement Category you might think of a method to return a collection of assignedInstruments() which for Guitar would return Fender, Alhambra, etc. You might augment this assignedInstruments(levelUp:BOOL) to get also those instruments of the category above.
Generally you must be clear about what the category assignment basically means. If you change the assignment the product will end up in another list.
It depends on the purpose of the diagram. Do you apply a certain software development method that defines the purpose of this diagram in a certain context and the intended readers audience?
Because you talk about a 'domain model', I guess your goal is to provide a kind of conceptual model, i.e. a model of the concepts needed to communicate the application's functionality to end users, testers etc. In that case, the first and the second diagram are both valid, but without the operations (FilterByCategory and GetCategories), because these are not relevant for that audience. The fact that the GUI only displays a subset of the full category tree is usually not expressed in a UML diagram, but in plain text.
On the other hand, if your intention is to provide a technical design for developers, then the third diagram is valid. The developers probably need a class to persist categories in the database ('Category') and a separate class to supply categories to the GUI ('CategoryTreeItem'). You are right that this distinction is not meaningful in the domain language, but in a technical design, it is common to have such additional classes. Please check with the developers if your model is compatible with the programming language and libraries/frameworks they use.
One final remark:
In the first diagram, you specified multiplicity=1 on the parent side. This would mean that every Category has a parent, which is obviously not true. The second diagram has the correct multiplicity: 0..1. The third diagram has an incorrect multiplicity=1 on the composition of CategoryTreeItem.
From my perspective your design is overly complex.
Crafting a domain model around querying needs is usually the wrong approach. Domain models are most useful to express domain behaviors. In other words, to process commands and protect invariants within the correct boundaries.
If your Product Aggregate Root (AR) references a Category AR by id and this relationship is stored in a relationnal DB then you can easily fulfill any of the mentionned querying use cases with a simple DB query. You'd start by gathering a flat representation of the tree which could then be used to construct an in-memory tree.
These queries could be exposed through a ProductQueryService that is part of the application layer, not the domain as those aren't used to enforce domain rules or invariants: I assumed they are used to fullfil reporting or UI display needs. It is there you could have a concept such as ProductCategoryTreeItemDTO for the in-memory representation.
You are also using the wrong terms according to DDD tactical patterns in your diagrams which is very misleading. An AR is an Entity, but an Entity is not necessarily an AR. The Entity term is mostly used to refer to a concept that is uniquely identified within the boundary of it's AR only, but not globally.

Pointers, Lists and Vectors attribute names necessary in the UML diagram?

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.

UML - association or aggregation (simple code snippets)

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.

Graphically Modeling Metaprogramming

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.

Resources