aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Design pattern to compare object based on inherited properties Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Design pattern to compare object based on inherited properties" Watch "Design pattern to compare object based on inherited properties" New topic
Author

Design pattern to compare object based on inherited properties

jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
Hi there,

I have the following problem (quite basic I know, I'm just not very seasoned in Java)

My data model is quite simple, I have a root object (document) and an inheritance tree structure that further specializes documents metadata.

Eg: Doc<--OutputDoc<--InvoiceOutputDoc

Now let's say that doc has a "date" property, an OutputDoc has a "content" property and an InvoiceOutputDoc has an "invoiceId" property.

Now, given a Collection of InvoiceOutputDoc, I need to be able to sort the Collection based on a criteria, where the criteria corresponds to a property.

My problems are the following:
- if InvoiceOutputDoc was to implement the Comparable interface, how should I fit in the criteria, since the compareTo method signature doesn't allow for a criteria
- how can I implement the compareTo method in such a way that if Doc were to get a new "time" property, I wouldn't need to change anything to the code of InvoiceOutputDoc to sort a collection of InvoiceOutputDoc based on the "time" criteria?

I'm sure this situation is typical but I can't figure out a design pattern for that.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Don't let the doc itself implement the Comparable interface, but implement a Comparator instead.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
Ok so how do I do that then?

Should I implement a comparator for each object of my data model? And then have the comparator's constructor signature include the sort criteria?

does the following make sense?

My worry here is that it is indeed extensible, but if I were to add a "time" property to Doc, I would have to modify the Doc class and the Criteria Enum. Is there a smarter way to do this?


Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
I would think about just implementing an InvoiceIdComparator. Not much sense to me in having a switch statement, if polymorphism can do the job as well.

The only way I can think of to have to implement/change a comparator when introducing a new field would be using reflection. I'd even guess that there are already some out there, in some open source project.
jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
The point of the switch statement is that InvoiceOutputDoc (and other objects in the Data Model) have more than just one property that can be used as base for the criteria.



Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
jean-gobert de coster wrote:The point of the switch statement is that InvoiceOutputDoc (and other objects in the Data Model) have more than just one property that can be used as base for the criteria.



Yes. And my point was that it might be a better idea to have a comparator per property.
jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
Oh ok, but that would mean hundreds of Comparators, since I have about a hundred different properties. Not to mention that this just moves the problem elsewhere because I'd have to determine which comparator I'll have to call the compare method upon. I'd still have to make a switch statement in the calling class instead of the comparator itself.

I guess you must be seeing something I don't, but like I said I'm far from being a guru. Could you explain how you'd do it with pseudocode perhaps?
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
jean-gobert de coster wrote:Oh ok, but that would mean hundreds of Comparators, since I have about a hundred different properties.


Well, that's better than having a hundred cases in a switch statement, as far as I can tell.

And, you can reduce the number of implementations you need by using reflection to access the actual field.


Not to mention that this just moves the problem elsewhere because I'd have to determine which comparator I'll have to call the compare method upon. I'd still have to make a switch statement in the calling class instead of the comparator itself.


In your version, who would decide which enum value to pass into the constructor of the comparator?


I guess you must be seeing something I don't, but like I said I'm far from being a guru. Could you explain how you'd do it with pseudocode perhaps?


Regardless of which Comparator implementation you use, somewhere and somehow you need to decide which field to sort by. Who decides that, when and how?
jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
The criterium to use will come from an http request. But you're right, at some point I'll have to map the HttpRequest parameter to an Enum I haven't gotten to that part of the imlementation yet. Maybe an Enum is not the right way to go, I'm not sure. I just don't want to start implementing an endless list of "if-elses", looks like an anti-pattern to me.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
The request parameter will be a string, that needs to be mapped to a comparator, right? I often use HashMaps for that purpose:



Does that sound reasonable to you?

(With just a little bit more effort, the map could even be filled from a configuration file.)
jean-gobert de coster
Ranch Hand

Joined: Dec 04, 2008
Posts: 49
Thanks very much for the idea. I had considered the idea of a hashmap but didn't think of a configuration file. Love the idea. Thank you
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
you're welcome!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Design pattern to compare object based on inherited properties