2

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...?
}
Community
  • 1
  • 1
koalaok
  • 5,075
  • 11
  • 47
  • 91
  • 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 Jan 05 '16 at 14:19
  • 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 Jan 05 '16 at 15:22
  • 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 Jan 16 '16 at 17:11

4 Answers4

1

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.

Prim
  • 2,880
  • 2
  • 15
  • 29
  • pls. see my added note to my question. About A/B. Sorry If I wasn't clear but this is not the point – koalaok Jan 05 '16 at 14:21
  • Diagrams are correctly implemented yes... but in real life, we don't draw as many diagrams for pleasure, diagram is draw by reflecting a real specific situation, and only one should be really logical according to the situation. But yes, your code reflect your diagrams ;) – Prim Jan 05 '16 at 14:24
  • I agree with you, this is just an "academic" question, not real life. – koalaok Jan 05 '16 at 14:26
  • Please note here it is one possible implementation but there are others too. You can add a class which role is to manage the link between two objects too. Depending on situation (and maybe on developer), one ore other implemention may be choosen to implement the purpose – Prim Jan 05 '16 at 14:28
  • The term "product" is ambigously used both for individual products and for product types. This is also the intended meaning of the class Product in the question. – Gerd Wagner Jan 14 '16 at 17:40
1

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
    }
}
Henrique Barcelos
  • 7,670
  • 1
  • 41
  • 66
  • I see, the only way to grant it, is by initialization and by writing a correct setter method. – koalaok Jan 05 '16 at 14:22
  • About this line : private List products = Arrays.asList(new Product[4]); I have been discussing with a collegue of mine and he said that it would be better to use Arrays like: Product[] products= new Product[2]; since your solution would waste more memory. What do you think? – koalaok Jan 07 '16 at 10:07
1

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.

qwerty_so
  • 35,448
  • 8
  • 62
  • 86
0

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.

Community
  • 1
  • 1
Gerd Wagner
  • 5,481
  • 1
  • 22
  • 41