I am designing a program that allows you to create an object with traits and then add it to a database. For example, a renting property like so:
public class Property
{
PropertyType type;
int bedrooms;
int bathrooms;
double squareFootage;
boolean furnished;
}
Then, you or other users can search the database for objects based on those traits. But here are the restrictions:
All properties have one of each trait defined (you can't leave one trait blank)
You may search for properties by any one trait, combination of traits, or no traits (to see all). AND you can specify a multiplicity for each trait. For example, you can specify a HOUSE with 2, 3 or 4 bedrooms and 2 or 3 bathrooms. Thereby not putting restrictions on square footage or furnishing.
This poses a problem, as the existence of a trait in the search criteria may or may not exist, and may have a multiplicity. Here is my current solution to hold the search criteria:
public class SearchCriteria
{
ArrayList<PropertyType> type;
ArrayList<int> bedrooms;
ArrayList<int> bathrooms;
ArrayList<double> squareFootage;
ArrayList<boolean> furnished;
}
The problem is that when I want to add another trait to Property
, I have to add it to both these classes (and probably more in database controller etc) and add additional functions for it in each. What is a design pattern I can utilize to make this code more modular and abstract?
Essentially, a good answer would be a solution that allows the addition or removal of traits by only changing one class/file.
Simply using an interface Trait
with an overidden function getTrait()
wouldn't work because the return types aren't the same across all traits.
EDIT: I have to implement a SearchCriteria
class because this program is run on a client/server connection, so SearchCriteria
will be serialized and sent over a socket, not sent directly to the database.
If you only have a handful of traits, and they're fundamental to your business model, it's totally reasonable to have to change more than one class when you add a new trait or want to change the type of behavior of one of those traits.
However, if you're trying to come up with a model that can handle dynamically adding different types of traits to your object, you may consider not encoding the traits as class properties at all. Rather, have your model contain a list of Traits, where each Trait knows its TraitType. Each TraitType has a specific shape for its data, as well as a specific shape for its Criteria. This would enable you to define your model in a file or database somewhere, and change it on demand, and only have to change the code when you identify a new TraitType. But it would also be an enormous amount of work, and would only be worthwhile if your business needs require a high degree of configurability.