【发布时间】:2021-10-11 14:22:57
【问题描述】:
我正在设计一个音乐信息系统。我有几个相互连接的实体。
以下是部分域代码。
class Album {
private Set<Track> tracks;
private boolean published;
public Set<Track> getTracks() {
return this.tracks;
}
public boolean isPublished() {
return this.published;
}
public void publish() {
System.out.println("Album.publish() called");
this.published = true;
this.tracks.forEach(track -> track.publish());
}
}
class Track {
private boolean published;
private Album album;
public boolean isPublished() {
return this.published;
}
public Album getAlbum() {
return this.album;
}
public void publish() {
// if track is single (this.album == null), set published to true
// if track is part of an album and the album is NOT published, return;
// if track is part of an album and the album is published, set published to true
if(this.album != null && !this.album.isPublished())
return;
this.published = true;
}
}
Track 是一个独立的实体。它可以是单首曲目(即没有专辑)。所以实际上需要album 属性。
一个域规则是,当专辑存档(即未发布)时,其曲目也不能发布,如果专辑已发布,则其任何曲目都可以发布或存档。
问题是当专辑发布时(例如album1.publish()),其曲目的publish()方法也会被调用。但是track1.publish() 根据已有的副本(未发布)检查专辑是否已发布。
我该如何解决这个问题?
【问题讨论】:
-
如果
Album是一个实体,则不应有“副本”——实体具有唯一标识,所有引用都应指向同一个对象。 -
正确。我应该如何在 Java 中实现它?据我所知,Java 总是按值传递。 @埃里克森
-
stackoverflow.com/questions/40480/… 很好地了解 pass-by-value 与 pass-by-ref
-
是的,将对父
Album的引用传递给Track(按值,因为所有引用都在 Java 中传递)。强制数据完整性的一种方法是删除直接为Track设置Album的任何API,而是仅在Album上提供addTrack(Track)方法,该方法更新轨道集合并设置Album通过包私有访问。
标签: java oop design-patterns pass-by-reference pass-by-value