确保Java中的UML约束?
假设我的应用程序设计为两类:确保Java中的UML约束?,java,model,uml,constraints,Java,Model,Uml,Constraints,假设我的应用程序设计为两类:Person和Company。还假设我定义了一个UML图,它定义了人和公司之间的一对多关系:每个人对象必须只属于一个公司,而公司可以包含许多人 有哪些最佳实践可以确保这一简单约束始终有效,即不存在一个时间点,即一个人对象包含在多个公司中?我想到了三种方法: 拥有完美、无bug的代码,永远不会违反我的任何约束。然而,作为一个现实主义者,我知道这是困难的或不可能的,特别是随着限制的数量增加 执行手动检查每个约束的ensureCorrectness()方法。在本例中,它将遍
Person
和Company
。还假设我定义了一个UML图,它定义了人
和公司
之间的一对多关系:每个人
对象必须只属于一个公司
,而公司
可以包含许多人
有哪些最佳实践可以确保这一简单约束始终有效,即不存在一个时间点,即一个人
对象包含在多个公司
中?我想到了三种方法:
拥有完美、无bug的代码,永远不会违反我的任何约束。然而,作为一个现实主义者,我知道这是困难的或不可能的,特别是随着限制的数量增加
执行手动检查每个约束的ensureCorrectness()
方法。在本例中,它将遍历所有人员
并确保只有一家公司
包含该人员
。否则,它将打印一个错误。我会经常调用这个方法
例如,使用Hibernate定义数据库模式并将数据存储到数据库中。在模式中,我可以定义一个约束来匹配UML图中的约束。然后,每当我将数据持久化到数据库中时,Hibernate将检查所有约束,如果出现问题,则打印错误
但我不禁想知道,在Java中是否还有另一种更干净的方法可以做到这一点,它不依赖于(1)完善,(2)手动验证,或(3)关系数据库。是否有一个库或框架允许我在代码中指定注释,类似于:
@一家公司(个人、公司)
或者更具体地说:
@OneToMany(个人、公司、个人)
假设公司
类有一个列表人员
成员变量
如果我想确保一个人的社会保险号码在所有人中都是唯一的,我可以说:
@唯一(Person.SSN)
Java是否存在类似的功能?首先,您可以通过将DB中的col设置为非空和客户id设置为唯一,在DB中轻松配置所有这些功能。
您可以在之前和之后使用触发器,以确保数据被删除或添加到数据库中
第二个选项,您可以使用散列映射来包含数据,从而设置java类上的所有DB
在我看来,第一种选择更容易 公司与个人之间的关系并不困难。例如,列出公司中包含的人员要素。您必须手动确保的一件事是列表中不包含单个人员的多个实例
另一种方法则更为困难。您必须手动检查(每个列表不包含同一个人的多个实例)。但您可以将其与前面的限制结合使用:
所有人员名单的长度应等于具有唯一人员的所有名单的长度
我对数据库了解不多,但我会选择第二个选项(EnsureRecorrectness)来检查上面的手动压缩。我会在Java中实现它:
public class Company {
Set<Person> persons;
...
public void addPerson(Person person) {
if (person.getCompany() != this) { // Avoiding an infinite loop between addPerson() and setCompany()
person.setCompany(this);
persons.add(person);
}
}
public boolean removePerson(Person person) {
return persons.remove(person);
}
...
}
public class Person {
Company company;
public Person(Company company) {
this.company = company;
}
public void setCompany(Company company) {
if (this.company != null) {
this.company.remove(this);
}
this.company = company;
company.addPerson(this);
}
...
}
上市公司{
设置人员;
...
公众人士(人){
如果(person.getCompany()!=this){//避免addPerson()和setCompany()之间的无限循环
个人、公司(本公司);
人。添加(人);
}
}
公共布尔removePerson(Person){
返回人员。移除(人员);
}
...
}
公共阶层人士{
公司;
公众人士(公司){
这个公司=公司;
}
上市公司(公司){
如果(this.company!=null){
本公司,移除(本公司);
}
这个公司=公司;
公司。addPerson(本公司);
}
...
}
在代码中,人员
不能有多个公司
,并且公司
有一个人员
列表。使用Person(Company)
构造函数,Person
至少分配了一个公司
编辑:要修改Set
(无重复项),必须通过调用Person.setCompany()
方法的addPerson()
方法。此方法将从以前的公司
列表中删除人员
,并将其添加到新的公司
列表中
在setCompany()
中,您必须调用addPerson()
,因为程序员可以直接将Person
分配给公司
,而无需首先调用addPerson()
,结合封装,我会选择#1。这样,必须100%无bug的代码量非常小
public class Company {
private List<Person> persons = new ArrayList<>();
private List<Person> publicPerson = Collections.unmodifiableList(persons);
public List<Person> getPersons { return publicPersons; }
public void addPerson(Person p) {
... ensure p is removed from old company
p.setCompany(this);
persons.add(p);
}
}
public class Person {
private Company company;
/* pkg-private */ setCompany(Company company) {
this.company = company;
}
public Company getCompany() {
return company;
}
}
上市公司{
私人列表人员=新的ArrayList();
private List publicPerson=集合。不可修改列表(个人);
公共列表getPersons{return publicPersons;}
公众人士(p人){
…确保从旧公司中删除p
p、 赛特公司(本公司);
增加(p);
}
}
公共阶层人士{
私营公司;
/*私人包装*/setCompany(公司){
这个公司=公司;
}
上市公司{
返回公司;
}
}
小心,此代码不是线程安全的
请注意,hibernate仅在保存到数据库时检查约束。由于缓存的原因,可能会出现不一致。但是如何阻止人员
对象出现在两个公司
人员
列表中?所以基本上你是说没有这样的f