Basic Class Design
-
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, Richard -
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, Richardrb157 wrote:
How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song.
You could have a dictionary with the artist as the key and a list of songs as the value, e.g.
Dictionary<Artist, List<Song>> songsByArtist = new Dictionary<Artist, List<Song>>();
You'd then have to loop through all the songs, loop through the artists, check if they already exists in the dictionary (if not add the key-value pair) and then add the song to the List in the value part. As for the further thinking I'm also having a think about it (too early in the morning (oops, afternoon :-O))
-
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, Richardrb157 wrote:
How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song.
Sure you can
class Song
{
List<Artist> artists;
// various other attributes
}class Artist
{
String name;
List<Song> songs;
//various other attributes
}class SongList
{
List<Song> songs;
} -
rb157 wrote:
How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song.
Sure you can
class Song
{
List<Artist> artists;
// various other attributes
}class Artist
{
String name;
List<Song> songs;
//various other attributes
}class SongList
{
List<Song> songs;
}Thanks, I did wonder about these sort of circular relationships and whether they are wise... i.e. if for some reason the Song and Artist objects do not replicate each other correctly then a different result is obtained when outputing song.artist[i] than artist.song[i]. However if circular relationships are generally considered appropriate, then I am quite happy with that approach. My concern is that in the real world the artist is probably not an attribute of the song and the Song not of the artist, in that one is not part of the other, just has an other type of relationship: In the same way that the Driver is not an attribute of a car. However if a driver is modelled in the same way as a steering wheel in its relationship then that is fine. I would appreciate comment on this point. The approach provided by Ed... This would work artist to Song, but I think that another list would be required to output song by artist:
Dictionary <Song, List <Artist>>
Which is fine but would appear to be an amount of processing which is far in excess of mike's suggestion. Thanks, Richard -
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, RichardI think it a classic design question. Do you keep data "heavy" to optimize queries or do you keep the data light and don't really care about performance for queries ? One other question to ask yourself is : What is the most important basic information ? is it the artist ? the song ? the CD (for example) ? Will you enter an artist and then all the song that he wrote ? Will you enter a CD with the artist(s) and all the songs? You have to remember that the data, in this particular case is really static; keeping cross reference should be easy.
Maximilien Lincourt Your Head A Splode - Strong Bad
-
Thanks, I did wonder about these sort of circular relationships and whether they are wise... i.e. if for some reason the Song and Artist objects do not replicate each other correctly then a different result is obtained when outputing song.artist[i] than artist.song[i]. However if circular relationships are generally considered appropriate, then I am quite happy with that approach. My concern is that in the real world the artist is probably not an attribute of the song and the Song not of the artist, in that one is not part of the other, just has an other type of relationship: In the same way that the Driver is not an attribute of a car. However if a driver is modelled in the same way as a steering wheel in its relationship then that is fine. I would appreciate comment on this point. The approach provided by Ed... This would work artist to Song, but I think that another list would be required to output song by artist:
Dictionary <Song, List <Artist>>
Which is fine but would appear to be an amount of processing which is far in excess of mike's suggestion. Thanks, Richardrb157 wrote:
I did wonder about these sort of circular relationships and whether they are wise
I apologize. I was in no way suggesting it was wise, only that it could be done. In order to know if it is wise much more information is required. I would also guess that a design utilizing one or more interfaces would most likely be superior.
-
rb157 wrote:
I did wonder about these sort of circular relationships and whether they are wise
I apologize. I was in no way suggesting it was wise, only that it could be done. In order to know if it is wise much more information is required. I would also guess that a design utilizing one or more interfaces would most likely be superior.
Thanks, can you give me an idea of the sort of things that I would need to consider in establishing if this was an apropriate approach, you also mention interfaces, in what respect might these be utilised? I understand what interfaces do, but can't quite work out how they assist in sorting out the relationships. Thanks, Richard
-
I think it a classic design question. Do you keep data "heavy" to optimize queries or do you keep the data light and don't really care about performance for queries ? One other question to ask yourself is : What is the most important basic information ? is it the artist ? the song ? the CD (for example) ? Will you enter an artist and then all the song that he wrote ? Will you enter a CD with the artist(s) and all the songs? You have to remember that the data, in this particular case is really static; keeping cross reference should be easy.
Maximilien Lincourt Your Head A Splode - Strong Bad
Thanks, my feeling at present is actually that I need to design for the mosst likely scenario, then provide a dictionary for the alternative. I expect that the default view will be of songs with the artists as a part of them. I feel really quite unsure about the cross referencing as it would seem to create far too much dependency between the two objects. It may work perfectly well, but I could find that I add a further attribute to song which is similar in the future, for example what if I add a rating to the song, made by a user I then have a link through user to rating and through rating through to song. The cross referencing may then become quite complex if I want to do some association regarding user rating of artists. I would rather then follow a common approach and provide a one way reference, with the return referencing created when a requirement develops to provide a dictionary type linking between user and artist. Does this make sense or would you think that the cross referencing up and down the 'tree' is still an appropriate way, or is my second scenario completely different and therefore it be appropriate to employ two approaches. I no that there are a lot of assumptions required here, but I would appreciate views on whether my thinking is sound. Many Thanks, Richard
-
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, Richard -
I am just trying to learn OOAD using c# at present, by designing a simple song management system. Within this system there are songs which have one to many artists. I therefore designed classes as follows:
class Song { Artist[] artists; // various other attributes } class Artist { String name; //various other attributes } class SongList { List<Song> songs; }
This seems to work OK I could in my output list each 'Song in songs' and show the artist by looping through each one in that song. Where I have got really confused is another requirement which I might have to list all Artists along with their songs. How can I build a collection of artists and list the songs for each artist if artist is an attribute of a song. I can after all do song.artist, but I cannot access song from the artist: artist.song. On thinking further I decided that an artist is not actually an attribute of song, but just a loose relationship. If they are just to seperate objects in a collection how do I implement this loose relationship between the two objects. Any help, including references to books or other material which may be of help would be greatly appreciated. I son't think that I am thinking correctly to understand this, so any help that will assist me in thinking the right way would be greatly appreciated. Thanks, RichardWhy don't you look at providing a Many:Many relationship between the songs and artists. Ok, sure this is best performed back in the data, but you can then easily place a "LINK" class between the Songs and Artists. That way you don't have a true circular reference but you will reap the benefits. Songs (1) ---> (M) SongArtistLink (M) <--- (1) Artists I'm using this approach in our own in-house solution on a number of various entities. In the songs class, add a Readonly Artists property which references the "LINK" class. In the artists class, add a Readonly Songs property which references the "LINK" class. We've seen no perceived or measurable performance penalties using this approach and because the link is done in "data" you can then query the data at any time using any of the available tools. Hope this helps.
Edward Steward edwardsteward@optusnet.com.au
-
Why don't you look at providing a Many:Many relationship between the songs and artists. Ok, sure this is best performed back in the data, but you can then easily place a "LINK" class between the Songs and Artists. That way you don't have a true circular reference but you will reap the benefits. Songs (1) ---> (M) SongArtistLink (M) <--- (1) Artists I'm using this approach in our own in-house solution on a number of various entities. In the songs class, add a Readonly Artists property which references the "LINK" class. In the artists class, add a Readonly Songs property which references the "LINK" class. We've seen no perceived or measurable performance penalties using this approach and because the link is done in "data" you can then query the data at any time using any of the available tools. Hope this helps.
Edward Steward edwardsteward@optusnet.com.au
Thanks, I had been considering this, and I think that it provides the most flexible solution and models the relationship correctly, artist is no more part of the song than say driver is of a car, they just have a loose relationship which is best modelled as that. Thanks again, Richard
-
Thanks, I had been considering this, and I think that it provides the most flexible solution and models the relationship correctly, artist is no more part of the song than say driver is of a car, they just have a loose relationship which is best modelled as that. Thanks again, Richard
Cool. The best thing I like about a M:M relationship (link table) is that is easy to replicate that model out to other entities. i.e. Songs & Albums, Artists and genres, etc. One of the things that I quite enjoy is the fact that I can use a single link table for multiple relationships. This is because we use a GUID as a primary key due to our replication needs.
Edward Steward edwardsteward@optusnet.com.au