2
votes

I'm quite confused about how to implement correctly in java code, associations drawn on a UML class diagram.

Imagine we have just two classes (i.e. Order and Product) with association specified in different ways, these associations could be drawn as following cases A,B or C: enter image description here

Since I've found this answer: https://stackoverflow.com/a/2293760/3248096 that talks about (association with an arrow and navigability direction)

My first question is about difference on implementing B compared to A. On A implementation I would write:

public class Order{
     private Set<Product> products; 
}


public class Product{
     private Set<Order> orders; 
}

On B implementation :

public class Order{
     private Set<Product> products; 
}


public class Product{
     //no references properties back to order from here since no back navigability
     ...
}

Second question is about C model: What's the best way (is there one?) to represent by implementation a limited cardinality from 0 to 4? (Doesn't have much sense that a Product could have 0 to 4 parent orders. It's more about understanding modeling vs. code)

public class Product{
     //Array(4) orders...?
}
4
Note: I'm not asking if A is better than B. Order Product have been chose just as an example, take them just as two entities with a relation. The focus is not about it is correct if a order as many product or viceversa. The relation could possibly be expressed as the A diagram or B. What I want to understand is if the B implementation satisfies the B diagram because of the added arrow.koalaok
I think A and B mean the same thing, that is the arrow is implicit in A, that order contains products. Therefore, your first implementation is wrong (two-way reference). Second one is correct. About C, it is hard to say what is going on without having some more information.Nazar Merza
A and B do clearly not mean the same thing. A leaves it open, if the association is realized as a bidirectional one (as suggested in the question) or as a unidirectional one (like in B). See my answer below.Gerd Wagner

4 Answers

1
votes

An Order have several Product, so having a collection of Product into Order seems correct.

In the other hand, a instance of Product should be associated to only one Order. There are maybe a kind of ProductModel shared between several Product, but an instance of Product should be linked to only one Order for me. So, no more collection is needed here, no more link too because we have already a link between an order and these products.

So B implementation seems to be ok.

For second question, C implementation, you should have either an array with 4 slots or a collection with unlimited size. In both case, you must have to add code to control the state when adding or removing an element. For example, check if order has not already 4 products before accepting adding a new product, and handle the case properly.

1
votes

About your question C.

Fixed-sized lists can be obtained this way:

public class Order {
     private List<Product> products = Arrays.asList(new Product[4]); 
}

See this link on ideone to see an example (please don't mind the public attribute, I'm just too lazy to write a setter method in this short example).

Code:

import java.util.*;
import java.lang.*;
import java.io.*;

class Product {

}

class Order{
     public List<Product> products = Arrays.asList(new Product[4]); 
}

/* Name of the class has to be "Main" only if the class is public. */
class Main
{
    public static void main (String[] args) throws Exception
    {
        Order o = new Order();
        o.products.set(0, new Product());
        System.out.println(o.products);
        o.products.add(new Product()); // throws UnsuportedOperationException
    }
}
1
votes

Okay, although asking multiple questions is not good style, here is an answer to A/B. Introducing navigability has only little semantics. It tells that you must be able to navigate in the direction of the arrow. So the originating class has a property of the class where the association points to. But in most cases from the design model it is obvious (from the methods implemented) which one needs a property for the other side. So you can leave it away with no issue at all.

Having said this, both implementations fulfill the design from the pure "arrow-context". The need for the private Set<Order> orders; arises from the overall system design. It would only be wrong if you left away private Set<Product> products; in the B-case.

0
votes

Your model A does only specify a many-to-many association between Order and Product. It does not yet specify how this association is to be implemented with the help of reference properties: as a unidirectional or as a bidirectional association?

Your model B is probably intended to express a unidirectional many-to-many association between Order and Product realized in the form of a reference property Order::products. Notce, however, that this requires a different visual notation because UML navigability arrows do not have much semantics (they do not imply a reference property, but could also be taken care of by a query-based retrieval method of the associated products). You would have to replace the arrow head with an "association end ownership" dot, as explained in this post.

Your model C is just adding an upper multiplicity constraint, which would imply that you have to prevent users from making a fifth order of the same product. Using Java Bean annotations, this constraint could be expressed like so:

@Size(max=4) Set<Product> products;

You may want to read more about this in my book chapter on Associations.