单向/双向X一对多X多对一关联关系 [英] Uni/Bi direction X One/Many X Many/One Association relationships

查看:135
本文介绍了单向/双向X一对多X多对一关联关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下问题也指以下问题中的讨论 https://stackoverflow.com/search?page=2& tab = Relevance& q = one%20to%20many%20unidirectional%20java

在OO中添加双向关系的最佳做法模型

我尝试在Java中实现由[单向/双向] X [(一个/很多)到(一个/很多)]形成的8个关联组合.我发现无法实现两种情况,即单向一对一和单向一对多(例如Person-> * Vehicle).其他6种组合和组合也可以通过编程实现.

我不仅感觉到Java的情况,这两种情况都不存在.例如用例-如果我们知道没有将Aadhar/SSN号分配给其他任何人,则只能分配一个Aadhar/SSN号(必须进行反向导航).这是否意味着我们在制作设计模型时必须注意不要到达这些特定的关联(尽管它们可能会出现在分析模型中)?我对此感到困惑.

解决方案

基本(无聚合)

如果您正在寻找基本的单向关联,那么这是所有这些中最简单的.

单向一对一

class Person {
    String name;
}

单向一对多

class Person {
    List vehicles;
}

综合聚合

如果我假设您要询问复合关系(一个SSN最多可以分配给一个人),那么您仍然可以实现它.

您如何决定实施它的精确度取决于您的特定领域,例如您存储数据的方式,因为

必须进行反向导航

实际上不是真的,因为您可以检查所有Person实例.或者,您也可以将所有SSN存储在一个智能数据结构中,该结构可以让您快速检查一个新的SSN是否唯一,然后您就可以将其分配给该人员,而无需进行其他检查,因为您已经知道它是唯一的. >

或者您也可以实现相反的查找,即使关联是单向的",也不禁止

引用 UML规范(11.5.3.1关联)[强调我的]:

可导航性意味着在运行时参与链接的实例(关联的实例)可以是 从协会另一端的实例进行有效访问.如此高效的精确机制 实现访问取决于特定的实现. 如果一端不可导航,则从另一端访问 可能或可能 ,如果可能的话,它可能效率不高.


根据评论更新

没有人声称必须在访问器中坚持关系约束.实际上,几乎总是会有暂时无效的关系,想像一下:

person = new Person();
// right now person is invalid state because it doesn't have an SSN
ssn = ssnGenerator.createNew();
// now ssn is also in invalid state because it has no person
person.setSSN(ssn);
// only now is person and ssn valid

(创建构造函数无济于事,因为构造函数是在对象已创建之后调用的(因此构造函数的另一部分可能需要已设置的ssn).

因此,程序员有责任确保系统以最有意义的方式支持所有约束.在某些情况下,使用构造函数/访问器是最简单的方法,但是您可以例如将以上代码包装在原子事务中.毕竟,如果您将验证保留在setSSN()中,那么如果程序员根本忘记调用该方法会发生什么?

(人1-> *车辆) p1.add(v1)和p2.add(v1)可能违规

您询问了人员-> *车辆",现在您将其更改为人员1-> *车辆",因此答案显然有所不同.但是,与上述相同的原则适用-维护所有约束是系统的责任,无论在访问器,验证方法或系统构建方式是实现细节的何处完成-没有唯一的最佳方法,并且总是会有权衡的.

Following question also refers to discussion in following questions as well https://stackoverflow.com/search?page=2&tab=Relevance&q=one%20to%20many%20unidirectional%20java

Best practise for adding a bidirectional relation in OO model

I tried to implementing 8 association combinations formed by [Unidirectional/Bidirectional] X [(One/Many) to (One/Many)] in Java. I found two cases can not be implemented namely Unidirectional One to One and Unidirectional One to Many (e.g. Person->*Vehicle). Other 6 combinations and Composition are possible programatically.

I Feel its not only the case with Java, these 2 cases do not exist. e.g. Use case - allocate one Aadhar/SSN number to only one person is possible if we know that number is not allocated to anybody else (reverse navigation is must). Does this mean we need to take care while making our design model not to arrive at these specific associations (though they might be present in analysis model)? I am confused on this.

解决方案

Basic (No Aggregation)

If you are looking at basic unidirectional association, then that's the simplest of them all.

Unidirectional One to One

class Person {
    String name;
}

Unidirectional One to Many

class Person {
    List vehicles;
}

Composite Aggregation

If I assume that you are asking about composite relationshions (where one SSN can be assigned to at most one person), then you can still implement it.

How exactly you decide to implement it is however subject to your specific domain or e.g. how you store your data, because

reverse navigation is must

is not actually true, because you can just check all Person instances; or you can store all the SSNs in a smart data structure that allows you to quickly check if a new one is unique, and then you would assign it to the Person without additional checks, because you already know that it is unique).

Or you can implement also the opposite lookup, which is not prohibited even if the association is "uni-directional"

To quote the UML Specs (11.5.3.1 Associations) [emphasis mine]:

Navigability means that instances participating in links at runtime (instances of an Association) can be accessed efficiently from instances at the other ends of the Association. The precise mechanism by which such efficient access is achieved is implementation specific. If an end is not navigable, access from the other ends may or may not be possible, and if it is, it might not be efficient.


Update from comments

Noone claims that upholding the relationship constraints has to be done in the accessors. In fact pretty much always you will have temporarily invalid relationships, imagine:

person = new Person();
// right now person is invalid state because it doesn't have an SSN
ssn = ssnGenerator.createNew();
// now ssn is also in invalid state because it has no person
person.setSSN(ssn);
// only now is person and ssn valid

(creating a constructor wouldn't help, because constructor is called after the object has already been created (so another part of the constructor could need the ssn already set).

So it is the responsibility of the programmer to ensure that the system upholds all constraints in whatever way it makes most sense. Using constructors/accessors is the easiest way in some circumstances, but you could e.g. wrap the code above in an atomic transaction. After all, if you kept your validation in the setSSN(), then what would happen if the programmer were to forget to call the method at all?

(person 1->* vehicle) p1.add(v1) and p2.add(v1) are possible violations

You asked about "person ->* vehicle", now you've changed it to "person 1 -> * vehicle" so obviously the answer differs. But the same principle as above applies -- it is the responsibility of the system to uphold all constraints, and wherever that's done in accessors, validation methods, or the way the system constructed is an implementational detail -- there's no single best way, and there will be always trade-offs.

这篇关于单向/双向X一对多X多对一关联关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆