如何通过给定的类图正确实现Java OOP代码中的关联?

时间:2016-01-05 14:00:16

标签: java oop uml

我对如何在java代码中正确实现,在UML类图上绘制的关联感到困惑。

想象一下,我们只有两个类(即Order和Product),它们以不同的方式指定关联, 这些关联可以如以下情况A,B或C得出: enter image description here

因为我找到了这个答案:https://stackoverflow.com/a/2293760/3248096 谈论(与箭头和导航方向的关联)

我的第一个问题是关于实施B与A相比的差异。 在一个实现我会写:

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


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

在B实施:

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


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

第二个问题是关于C模型: 什么是最佳方式(有一个吗?)通过实现从0到4的有限基数表示? (没有多大意义,产品可能有0到4个父订单。它更多的是关于理解建模与代码)

public class Product{
     //Array(4) orders...?
}

4 个答案:

答案 0 :(得分:1)

订单有多个产品,因此将产品收集到订单中似乎是正确的。

另一方面,Product的实例应仅与一个Order相关联。可能有一种ProductModel在多个Product之间共享,但Product的一个实例应该只链接到一个Order。因此,此处不再需要收集,也不再需要链接,因为我们已经在订单和这些产品之间建立了链接。

所以B实现似乎没问题。

对于第二个问题,C实现,你应该有一个包含4个插槽的数组或一个无限大小的集合。在这两种情况下,您必须添加代码以在添加或删除元素时控制状态。例如,在接受添加新产品之前检查订单是否还没有4个产品,并正确处理案例。

答案 1 :(得分:1)

关于您的问题 C

可以通过以下方式获得固定大小的列表:

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

请参阅此link on ideone以查看示例(请不要介意公共属性,在这个简短的示例中,我只是懒得编写setter方法)。

代码:

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

答案 2 :(得分:1)

好的,虽然问多个问题并不是好的风格,但这里是A / B的答案。引入导航性只有很少的语义。它告诉您必须能够沿箭头方向导航。因此,原始类具有关联指向的类的属性。但在大多数情况下,从设计模型中可以明显看出(从实施的方法中)哪一个需要另一方的属性。所以你可以毫无问题地离开它。

说到这里,两个实现都完成了纯粹的&#34; arrow-context&#34;的设计。 private Set<Order> orders;的需求来自整个系统设计。如果你在B案件中遗忘private Set<Product> products;,那就错了。

答案 3 :(得分:0)

您的模型A仅指定OrderProduct之间的多对多关联。它尚未指定如何在参考属性的帮助下实现此关联:作为单向或双向关联?

您的模型B可能旨在表达OrderProduct之间以参考属性Order::products形式实现的单向多对多关联。然而,请注意,这需要不同的视觉符号,因为UML可导航性箭头没有太多语义(它们不暗示引用属性,但也可以通过相关产品的基于查询的检索方法来处理)。您必须使用“关联最终所有权”点替换箭头,如this post中所述。

您的模型C只是添加了一个上部多重约束,这意味着您必须阻止用户制作同一产品的第五个订单。使用Java Bean注释,此约束可以表示如下:

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

您可能希望在我的book chapter on Associations中了解更多相关信息。