If we create an additional layer of abstraction by creating a RoomDTO to transport data to and from the client, and it lets us to operate on business logic in less error-prone and more clean way, shouldn't we use also the same level of abstraction for search criteria?
Instead of do
And add a translation SearchCriteria -> String to use String as an input for Data class.
Do you think it would be more consistent or do you think it would be overengineering?
1. Yep, that what it is - the Room object holds the room data (all from the data schema) plus the record number. The record number is added to the Room by the business layer, as it's the first place where the DTO starts to live and where it's translated to/from String for Data class.
2. I was thinking about something like
And the business logic would unwrap the criteria into String for the data class.
Of course the method could be modified to:
Where the RoomCriteria could be an enum to be less error-prone.
Edit: Just thinking... Maybe the SearchCriteria should just extends Room object - and then you could provide criterias by using standard setters like:
I think it would be more easily for the future developers (and for me ;-) to reuse the Room class. Going further, there could be an interface Criteria which would have a method
which will be implemented by the particular SearchCriteria object. This way, not only Rooms could have defined criteria but any other object in the future.
So it would be something like
EDIT 2: Ok, maybe the inheritance isn't the best idea, as from logical point of view it says that "search criteria is a type of room"... Maybe more adequate would be to use an instance variable.
Well, first, I think it is much better to work with objects rather than with String , because this solution is more object-oriented.
Now, your Room object doesn't have to carry the record number field, because this isn't a concern of a Room. Record numbers should only be controlled in/by the Data class. For your search, you can return Map<Integer, Room>.
I like the way you think about a SearchCriteria object. You can have something like Hibernate's Criteria interface. Just take care not to make something that fancy, it doesn't even have to be an interface. It just has to be something simple that can do the job, with the and/or operators. I think you're in the right path.
Now, I don't like the idea of having the SearchCriteria class extending the Room class. Because a search criteria isn't a room. This is the worst scenario to use inheritance (to reuse code). In these cases, always consider using composition/aggregation rather than inheritance.
Roberto Perillo wrote:Now, your Room object doesn't have to carry the record number field, because this isn't a concern of a Room. Record numbers should only be controlled in/by the Data class. For your search, you can return Map<Integer, Room>.
It seems to me that in a world of Hibernate and Seam, etc. (even though they're not used in this project!), it's ok to have an identifying id in an entity such as a room or subcontractor object.
David Byron wrote:It seems to me that in a world of Hibernate and Seam, etc. (even though they're not used in this project!), it's ok to have an identifying id in an entity such as a room or subcontractor object.
Yes, you are correct! But the thing is, in this assignment, the Room class has the database fields, and there isn't a field we can consider unique per room, and that's why I suggested not adding the record number to the Room object, and only control it in the Data class (for instance, in a Map<Integer, Room>).
EDIT: Forgot to add that I've added SearchCriteria class which holds the map of SearchableRoomField => String. It has one method - addMatchExactCriteria(SearchableRoomField field, String value) which simply adds record to this map and returns this object (which allows for cascade execution like in Hibernate style). It acts only as AND operator.
It also have a package visible method which transforms the criteria to String which can be read by the database.
I will point that future enhancements of search operations could be made in this class (add OR operator, range operators, prepare for other entities than Rooms, etc.).
I would keep String because there is enough stuff in String api. Using a SearchCriteria class is, in my opinion, overengeneering.
In a real case, if you need some complex upgrade, you would prefer to start your upgrade from String class rather than from SearchCriteria class.