Reputation: 694
Let's say I have two classes: one for Band and one for CD. I want to be able to access easily all CD from one Band and to find the Band of a CD.
My solution is to have a field Band
in CD, and a ArrayList<CD>
in Band.
But I don't find this is a good solution. Does anyone know of a better design for this scenario?
Upvotes: 6
Views: 2203
Reputation: 1511
I see why you dislike the solution.
You are only storing the information once, but you have to update changes in both classes.
If you change the Band
of a CD
, you have to remove the CD
from the old Band
, set the Band
in the CD
, then add it to the new Band
.
That is of course complicated and prone to error.
Your classes don't have simple getters/setters. Instead, you have to implement a lot of logic in your domain classes to keep consistency.
The advantage is, of course, that you always have a the Band
of a CD
accessible and vice versa. Its a trade-off. A neccesary one, should you, for example, use a CD
's Band
as part of its equals
implementation.
Here is an interesting alternative, that may be advantegous in some situations:
Use your classes Band
and CD
only as simple POJOs and use another class (i.e. MusicService
) to resolve the relation:
class MusicService {
Band getBand(CD cd);
List<CD> getCDs(Band band);
addCD(Band band, CD cd);
}
Upvotes: 4
Reputation: 4750
You are not storing the information twice: CD just holds a pointer to the class Band. If would have done in C++ then this would have required some thinking (e.g. a weak_ptr to Band in CD to avoid circular references), but in Java the GC will take care of removing both objects when Band is not referenced anywhere else.
You can ensure some consistency (like a CD is only in one band) by writing some code that takes care of this, like the code below (WARNING: NOT TESTED):
class Band
{
private List<CD> m_cds;
public void addCD(CD cd)
{
id(cd.getBand() == this)
{
return;
}
if(cd.getBand() != null)
{
cd.getBand().removeCd(CD cd);
}
cd.setBand(this);
m_cds.add(cd);
}
public void removeCd(CD cd)
{
cd.setBand(null);
m_cds.remove(cd);
}
}
class CD
{
private Band m_band;
public void setBand(Band band)
{
m_band = band;
}
public Band getBand()
{
return m_band;
}
}
Upvotes: 0
Reputation: 17971
Your solution totally makes sense. Actually that's the principle JPA
works with.
See Java Persistence/OneToMany. JPA is a pretty good reference on how implement your own ORM.
Upvotes: 1
Reputation: 1
You could have a Set
of CDs in the Band class.
Alternatively, keep a unique ID in the Band class which will map each unique Band with multiple CDs.
There is no need to have a Band field in CD, as per my understanding.
Upvotes: 0