views:

39

answers:

2

Hi all, I'm not sure how to design a couple of classes in my app. Basically that's a situation:

  • each user can have many preferences
  • each preference can be referred to an object of different classes (e.g. album, film, book etc)
  • the preference is expressed as a set of values (e.g. score, etc).

The problem is that many users can have preferences on the same objects, e.g.:

John: score=5 for filmid=apocalypsenow 
Paul: score=3 for filmid=apocalypsenow 

And naturally I don't want to duplicate the object film in each user.

So I could create a class called "preference" holding a score and then a target object, something like:

User{ 
  hasMany preferences 
} 

Preference{ 
  belongsTo User 
  double score 

  Film target   
  Album target 
  //etc 
} 

and then define just one target. Then I would create an interface for the target Classes (album, film etc):

Interface canBePreferred{ 
  hasMany preferences 
} 

And implement all of those classes. This could work, but it looks pretty ugly and it would requires a lot of joins to work. Do you have some patterns I could use to model this nicely?

Cheers, Mulone

A: 

The preferences have a relationship with both the users and the objects. There may be one or more preferences expressed by a user. There may be one or more preferences expressed about an object.

To put it in data modeling terms, user has a 0 to N relationship with preferences, and object has a 0 to N relationship with preferences.

The preferences should be a separate class from the users and the objects.

Gilbert Le Blanc
Thanks!Is there an elegant way to model a relationship with different classes?Now I would do it with different members: Film targetFilm Album targetAlbum etc...But this is pretty ugly and requires logic.Any idea?
Mulone
besides, is it possible to use interfaces in Grails?I couldn't find doc about it.
Mulone
Sorry. I'm a data modeler, not a Grails developer. As far as your object, you could have one huge class that has all of the elements of all of the different objects you want to model. A bit wasteful on space, but conceptually simpler.Or, you could have a base object class, defining the common elements, and have your film and album classes inherit the base object and define the elements specific to film and albums, respectively.
Gilbert Le Blanc
Your database tables would mirror your class structure. Either one huge object table, or a base table with the common elements and child tables with the elements specific to each type of object.
Gilbert Le Blanc
The preference table would have a relationship with the base object table. The base object table would have a parent relationship with the other object tables.
Gilbert Le Blanc
A: 

I prefer the notion of creating an interface such as IPreferrable which I believe is supported in Grails via the Groovy foundation. I agree that the preferences should be seperated from the user object, but if the other objects effectively represent your preference taxonomy, you may be able to reuse them when building the preference object graphs. From a domain modeling perspective there is nothing wrong with what you proposed, but the user object can become fairly hefty.

From a persistance stand-point... since these are just preferences you may be able to get away with serializing the entire preferences object graph to XML. Depending on your database engine you can use SQLXML which means you still native XML DOM types and native query support via XQuery / XPath. This should not be done to avoid proper database design but is reasonable in some cases. With all that in mind, (de)serialization is always more expensive from a performance perspective, although transformation to things like JSON objects, Meta tag structures, and other formats becomes easier. There are certainly other ways to deal with this, but since you wanted alternatives this is just one more option.

JoeGeeky