简体   繁体   中英

How to implement correctly an association in Java OOP code by a given class diagram?

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 (ie Order and Product) with association specified in different ways, these associations could be drawn as following cases A,B or C: 在此输入图像描述

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...?
}

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.

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
    }
}

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM