What is the best way to model priority/preferences in a domain?
E.g. assume I have a class Person
representing a person and has some preferences e.g. PersonX
likes pizza, spaggetti and omelete and actually he would prefer spagetti over pizza.
How are these best modelled?
The first thought would be just to put them in a List
(as member variable of Person
) keeping the preference according to insertion order e.g. the first in the list is the most prefered, then the second in the list the second most prefered etc but this seems to me to end up being too tedious. E.g. when I want to do searches or associations for preferences etc.
Perhaps there is a standard approach for problems like this?
问题:
回答1:
You could use the list as you proposed and add a method to your Person class that would return a Comparator<Preference>
which would be able to compare 2 preferences for that person:
Person somebody.addPreference(pizzaPreference);
Person somebody.addPreference(omelettePreference);
....
Comparator<Preference> c = somebody.getPreferenceComparator();
boolean prefersPizzaOverOmelette = (c.compare(pizzaPreference, omelettePreference) > 0);
boolean hasNoPreferenceBetweenPizzaAndOmelette = (c.compare(pizzaPreference, omelettePreference) == 0);
And the comparator would simply check the index of the preference in your list (if it contains that preference etc.).
回答2:
You could use a priority queue for representing object priorities, and define an appropriate Comparator
for your class that takes into account the rules described. The queue uses a priority heap that will take care of maintaining the objects sorted by priority as they're being inserted.
回答3:
Preference
as a whole is a complete Entity in its own, though would not have any meaning unless it is associated with any Person
but can live on its own.
As far as Preference priority is concerned, Preference
doesn't have any priority Omelet, Pizza are all alike, but it has a priority when it is associated with a Person (say I like Pizza more than omelet, depends on me not on Pizza or Omelet).
So you have a Preference
and Person
object.
Now Preference will vary from Person to Person so you will associate Preference with Person.
Since priority is very much dependent on Person you have multiple options to achieve:
- Use PriorityQueue - While adding Preference assign the priority. This queue will be present in Person class itself
- Use Custom Comparator (As suggested by @assylias)
- Add Rules to Preference(based on location, gender, e.t.c.) and have pre configured rules which when given certain criteria will return the preference as calculated by System, though have a manual override of this.
In this case you can just use
PriorityQueue
.
回答4:
Use a class structure like this...(pardon the sloppy Java...I'm a C# guy)
public class PersonPreference
{
public Preference preference;
public int rank;
}
Then, allow your users to sort their preferences (hence, the rank column), and order on that property/column when necessary.
EDIT
Looking at this again, I want to redefine my class. A preference should be a user's like in comparison to another like...
public class PersonLike
{
public string like;
public int rank;
}
This new class defines something a person likes, and it allows for a rank so that when you have many instances of this class (or a data representation of it), they can be ranked, which in affect, creates the preference, because a preference is essentially a user liking something over something else. A like by itself is not a preference because it is not being compared against anything else.
This approach allows for n interests to be ranked against each other creating a large collection of preferences.