1

假设我的应用程序设计有两个类:PersonCompany. Person还假设我定义了一个 UML 图,它定义了and之间的一对多关系 Company:每个Person对象必须完全属于一个Company,并且 aCompany可以包含许多Persons。

有哪些最佳实践可以确保这个简单的约束始终成立,即永远不会有一个时间点Person包含多个对象Company?我想到了三种方法:

  1. 拥有永远不会违反我的任何约束的完美、无错误的代码。然而,作为一个现实主义者,我知道这是困难的或不可能的,尤其是随着约束数量的增加。

  2. 实现一种ensureCorrectness()手动检查每个约束的方法。在此示例中,它将遍历所有Persons,并确保恰好一个Company包含该Person。如果没有,它会打印一个错误。我会经常调用这个方法。

  3. 例如,使用 Hibernate 来定义数据库模式并将数据存储到数据库中。在模式中,我可以定义一个约束来匹配我的 UML 图中的约束。然后,每当我将数据持久化到数据库中时,Hibernate 将检查所有约束并在出现问题时打印错误。

但我不禁想知道在 Java 中是否有另一种更简洁的方法来做到这一点,它不依赖于 (1) 完美,(2) 手动验证,或 (3) 关系数据库。是否有允许我在代码中指定注释的库或框架,类似于:

@OneToMany(Person, Company)

或者更具体地说:

@OneToMany(Person, Company.persons)

假设Company该类有一个List<Person> persons成员变量。

如果我想确保一个人的社会安全号码在所有Persons 中都是唯一的,我可以说:

@Unique(Person.SSN)

Java有这样的东西吗?

4

4 回答 4

0

我会选择#1,结合封装。这样,必须 100% 无错误的代码量非常少

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

小心,这段代码不是线程安全的!

请注意,如果您保存到数据库,hibernate 只会检查约束。由于缓存,可能会出现不一致。

于 2013-06-07T13:34:03.877 回答
0

The relation between a Company to Person is not difficult. Make e.g. a list with Person elements contained in Company. The one thing you have to ensure manually is that the list does not contain multiple instances of a single Person.

The other way around is more difficult. You have to manually check this (that each list does not contain multiple instances of the same Person). But you can combine it with the previous restriction:

The length of all lists of persons should be equal as the length of all lists with unique persons.

I do not have much knowledge about databases, but I would go for the second option (ensureCorrectNess) to check the manual constriction above.

于 2013-06-07T13:18:36.487 回答
0

I would implement it like that in 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);
    }
    ...
}

In code, Person cannot have more than one Company, and Company has a list of Persons. With the Person(Company) constructor, Person has at least one company assigned.

EDIT: To modify the Set (no duplicates), you have to pass through the addPerson() method that call the Person.setCompany() method. This method will remove the Person from previous Company list and add him to the new Company list.

In setCompany(), you have to call to addPerson(), because programmers can assign directly a Person to a Company without calling first to addPerson().

于 2013-06-07T13:20:11.540 回答
-1

首先,您可以通过将数据库中的 col 设置为不为 null 并且客户 ID 唯一来非常轻松地在数据库中配置所有这些。您可以在前后使用触发器来确保将数据删除或添加到数据库中。

第二个选项,您可以通过使用哈希映射来设置 java 类上的所有数据库以包含数据。

在我看来,第一个选择更容易..

于 2013-06-07T13:18:16.607 回答