How to represent merchandise flavours (or product variants)? - uml

I have the following UML diagram:
Where VarietyCategory could take values like size and colour, and Variety for size could be S, M, L, and for colour could be green, red.
Now I can have a stock per combination of varieties, taken from the Cartesian product of all the variety categories a merchandise have (for example, 5 S-green items and 10 M-red items). How can I add this information to the UML diagram?
I guess I'm seeing this as an optional association class from Merchandise to the space defined by the Cartesian product of all the VarietyCategorys with a quantity attribute specifying the stock for that given combination, but I can't see how to express that in UML.
After thinking a bit I've come up with this, but this doesn't seem to fully convey the intention, as I had to put a note to specify a multiplicity depending on another part of the diagram, along with the constraint of selecting a variety from each variety category:
Any better ideas on how to do this?

The problem
This is indeed a popular scenario in some industries such as apparels, where each item in the catalogue is configurable regarding size, color and style.
The stock of a configurable merchandise such as "Shirt" does not make sense except for statistical purpose, but what really matters is the stock of the configured merchandises, e.g. {Item: "Shirt", size: "M", color="white", style:"italian colar"}. Here it's even more complicated, since the configuration elements are dynamic.
Your solution
Your second diagram models this very well by using a combination that you've called Flavor. So for the shirt, each possible combination of the configuration variables (Variety), e.g. the tuple ( "M","white","italian colar) would be a distinct flavor. Your association would class would hold the stock quantity of the Flavor.
The multiplicity on the Variety side would be by deduction 1..*. The constraint then needs to express that for an occurence of Flavor, the size of set of associated Variety occurrences is the same than those indirectly associated with the Merchandise. A full-text expression like you did is just fine. The other alternative would be to express this with a complex OCL predicate, which is very difficult considering some missing role names and the multiple indirections. Btw, most readers wouldn't anyway understand it.
However, I would not keep this solution:
Its main weakness is that the Flavor seems independent from the Merchandise, whereas in reality it only makes sense for a given Merchandise (your constraint proves it).
It is not easy to manage more complex stock, for example if you'd have a stock per warehouse.
Better alternatives
If you'd consider Flavor as a flavor of a given Merchandise, you could make this explicit and simplify the design: Flavor would become the configured Merchandise (instead of just a combination of Variety) and could make it a component of the Merchandise composite.
You could then simplify and store the stock quantity at the level of the Flavor . Or you could manage the stock quantity in an association class between the Flavor and a Warehouse (which you could not really do with your current model).
Everywhere you'd use a Merchandise, you'd use a Flavor instead, facilitating for example the ordering or the shiping of configured products, which is much more difficult if you'd keep the flavor independent of the merchandise.
To avoid confusion, it would nevertheless be better to rename Flavor in something more explicit that reminds that it's a product that you manage in your system.

A product variant (like Tesla's Model 3 in Pearl White with Sport Wheels) for a product (like Tesla's Model 3) has all features of the product (like a top speed of 140 mph) and additionally a set of attribute-value slots for all variation attributes of the product (like "Paint" and "Wheel" in the case of Tesla's Model 3). This is described by the following class diagram:
The diagram includes data samples next to classes for illustrating their meaning.
Notice that using composition for associating variation attributes to products and variation attribute values to variation attributes means that these attributes and their values are specific and not shared among products/attributes.
A corresponding relational database schema can be read off from this model:
products( id, vendor_id)
product_variation_attributes( id, product_id, name)
variation_attribute_values( id, product_variation_attribute_id, value)
product_variants( id, product_id, price)
variant_slots( product_variant_id, product_variation_attribute_id, variation_attribute_value_id)
This model/schema is compatible (modulo renaming) with the confirmed answers
https://stackoverflow.com/a/19200349/2795909 and https://stackoverflow.com/a/24941744/2795909.

Related

What's the difference between these types of association in an UML Class Diagram?

I never understood the difference between these types of association. How should I interpret and in which scenarios should I use each one?
Given your diagrams all three cases are equivalent. So, I would go with the simplest version.
Adding a Purchase class allows to define features and behaviors of the link objects.
In the second case, Purchase is classifying the binary links between User objects and Product objects. That means each Purchase object is the link between exactly one User object and exactly one Product object. The outcome is the same as in the third case. Only there you have two link objects and one regular object, making the model a little more complicated. On the other hand, in this case you don't need to explain to your readers what an AssociationClass is.
In earlier versions of UML the two latter cases had a subtle difference. If the two ends of the AssociationClass are unique, each pair of User and Product can have at most one link. For a Purchase this is probably not what you want, because the user might buy the same product multiple times. But a stack overflow user can earn each badge only once. The AssociationClass would allow to model this.
Unfortunately this distinction has been thrown out. Therefore, AssociationClasses now don't have more expressive power than regular Classes, making them obsolete. I wrote a specification issue asking to put uniqueness back in.
So, according to my college teacher, the first and second one are equivalent. The second one would be "more correct" if the purchase had other atributes, since it doesn't you would opt for the first.
The third one differs a bit from the rest in the way that there can be multiple purchases where the User X bought the Product Y.
So, the first and second would be useful if we only want one record of a purchase between a User and a Product, and the third if we wanted to keep a purchase history for example
The first one is a named association. The name of the association (being purchase) is pretty pointless unless you are doing some exotic stuff. In this case User and Product have both some array referencing objects on the other side.
The second and third are just alternative notations for the same thing. That is you have an association class Purchase which in this case connects User and Product by adding some (not shown) functionality/attributes. Here the classes left/right do not see each other. It's only Purchase which makes the references.
Edit As noted by #JimL. the 2nd and 3rd differ in one respect: #2 has two* left and right where there should be a 1 to make it a match for #3. This would be the usual use for an association class. The * would make it different and probably very uncommon for the obvious application here.

How to express counter type entity with UML?

I would need some help with a problem we're facing in a company, trying to model every process and entity.
So far we have used an enhanced conceptual model with entities and attributes with relationships but there are some objects that don't exactly match a dimension or a fact table, and this is an entity that can be called "Shops with sales over X units". There is the entity "sales" and "shop" obviously, that would have it's representation in UML as independent entities and represent at the lower level, each sale and shop.
What we need to indicate in UML is an entity that stores the counter of shops with sales over X units, so this has some kind of behavior or conditions.
If we consider the entity, it would need date-from and date-to, and the value (counter), and creating a connection with the shop entity seems enough, but we miss the behavior that expresses "more than x sales". So the behavior could be for example: Go to the shop entity, take the 1st element and navigate to the sales entity, calculating the sales. If it's over X, then value+1, and so on.
I made a simple version of the problem. Blue boxes represent the entities already created, and the orange one is the counter that should count the shops with some constraints.
Is there any way of using some kind of UML diagram that can help us to solve this problem?
You could realize that with an association class:
ShopSales relates Shop and Sales so you can store the number of sales along with other things you might need in that conjunction. The ShopSalesStats could give you the shops by number of sales.
Another (of many) way(s) would be to just hold the count as public property of Shop and let ShopSalesStates handle the counts on all associated Shops.

How to model attributes dependencies between different classes in UML object diagram?

In scope of visualizing different parts of the system I would like to exactly show dependency between different attributes.
In my case the use case will be in UI where a User have to to choose Country and based on his selection values for Product have to be updated in corresponding dropdown eg.
Values for Class Country:
Country1
Country2
Country2
Values for Class Product:
Product1 (available ONLY for Country1)
Product2 (available for Country1 AND Country2)
Product3 (available ONLY for Country2)
Product4 (available ONLY for Country3)
I've read about derived properties and constraints as it might be my case.
Also some links might be related to the same issue:
https://softwareengineering.stackexchange.com/questions/386816/how-to-model-attribute-dependency-inside-one-class-in-uml-class-diagram
But for now I do not have a working solution.
For general purpose I've tried to represent these relationships with abstract Class diagram but it's hard for me to do this with exact values of these Classes within Object diagram
You would likely model that as association class:
The CountryProduct needs to filled with the according information (so it my contain the price which is used for a product in a country).
You "could" model that as constraints on the association between Product and Country as well. But I'd bet that business will not be happy with that since it sets all in concrete when coding, while business expects quite some flexibility here.
Just use an Association between Product and Country. If you want to capture attributes for each Product-Country-pair, such as the price mentioned by #Thomas, an AssociationClass is the natural choice.
In an Object-Diagram Instances of the Association (links) can be shown as lines. You would have lines between Country1 and Product1, and Country2 and Product2 and Product3...
This could be used to illustrate the structure of your system and how it evolves over time. To really define it, other diagrams are better suited.
I don't see, how constraints on the Association can help. Textual Constraints could be on some additional Class Selection. The start of the constraint could be: context Selection: product = product1 implies country in (country1). This would not allow to later add new products. And the constraints defined by the Links between countries and products are much more readable.

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.

Conceptualization: generalization or not?

I'm modeling an app which will let users look for real estate properties. So it's going to be a website where users will be able to look for rentals and sales on houses, flats, castles, grounds, shops, parkings, offices. According to that, I'm hesitating in the class diagram. Should I generalize all the type of real estate properties, written above, from the class RealEstateProperty or should I just associate to it a class TypeOfRealEstate, knowing that the type "Ground" for example can be as well a real estate property as the ground of a property like a House or a Castle. Also a parking can be a real estate property as well as a parking of a House.
Anyone has an idea of what's the best way to do that ? Thanks in advance.
It depends of what features of different RealEstates your system has to implement. A class's features include attributes, methods and associations.
If all your potential RealEstates have same features, for example ID, type, price, date and responible agent, and you don't need to firther differenciate among them, than the associated type will do the work. Model RealEstateType as an Enum (or even class, if you expect to add new types) and associate it to a single RealEstate class.
If different RealEstates, on the another extreme, need to have different features, you will need to inherit those from the base abstract class. For example, Ground have an attribute "area", while building has "number of floors". Even methods can be different, or associations.
Following your example, you would like to link Ground to House. This is much cleaner in the second version - just an association between Ground and House class. In one-class version, you would have to link the RealEstate with itself and add spacial restrictopns (very "ugly" design).
In summary, try to think about the features of different RealEstates and make your RealEstate hierarchy based on their differences.
You can end up with a single class or several dozens of them. :) Try to keep this hierarchy as simple as possible (less classes), but enough to mark their different features clarly.

Resources