在DDD中如何封装对集合的访问?

4

在锻炼您的DDD技能时,假设您有以下对象:

class Person {
    Set<Address> addresses = new HashSet<Address>();
}

是否更适合允许对集合进行正常/完全访问:

Set<Address> getAddresses() {
    return addresses;
}

如果允许调用者根据需要添加/删除地址,这样做是否更好?或者在这种情况下,让调用者通过Person对象进行操作是否更好:

Set<Address> getAddresses() {
    return Collections.unmodifiableSet(addresses);
}

void addAddress(Address address) {
    addresses.add(address);
}

void removeAddress(Address address) {
    addresses.remove(address);
}

第一种情况可以避免我们创建额外的方法;第二种情况允许Person对象知晓其地址的变化(如果由于某种原因它关心这个问题)。在这里是否有最佳实践?
5个回答

3

我更喜欢第二种方法,但我认为不可修改的集合除了在客户端带来不必要的麻烦之外,几乎没有什么价值。

如果你想向客户表明这个集合是不可变的,那么你应该使用一个在其API中禁止变化的集合类型(而不是在其实现中)。也就是说,调用一个被声明存在的方法并捕获UnsupportedOperationException异常,就像在你与第一次约会的女人身上找到一个单位。

我很喜欢Josh Bloch,但我认为他在这件事上搞错了。


1
总的来说,我认为第二种方法更加健壮。使用不可修改的集合作为返回值可以防止外部人员改变Person类的内部状态。如果Person类在逻辑上拥有他们的地址,则其他人不应该能够在不经过Person类方法的情况下进行更改。

0

无论哪种方式都可以,但为了清晰起见,我会根据返回的集合是否可变来给方法命名:

Set<Address> getAddresses() {
    return Collections.unmodifiableSet(addresses);
}

Set<Address> addresses() {
    return addresses;
}

0

我无法看出这2种方法的优劣。它完全取决于您的类愿意提供什么功能。


0
这完全取决于您的需求。如果有充分的理由将底层集合与类的客户端隔离开来,那么就这样做。否则,提供set/get方法通常没有任何不利影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接