I've been pondering my choices for URLyBird data access layer, since I've a few doubts.
- Vacation (the value object): I would like it to be immutable. Which means that updateRecord will basically be an "overwrite", writing all the fields once again. Does it feel ok for you ?
- Vacation validation: I plan to try to validate each field of the vacation in the constructor. Issue is that it might throw InvalidParameterException + ordering of the test: to get an int from a String, I do (pseudo code in the constructor):
does it feel ok ? I ask the question because in SCJD Exam with J2SE 5 they don't do any data validation, whereas I'm planning to do it extensively for each field...
- regarding the record number, am I right in saying that's something made up ? Like something incremented on each vacation read ? If so, I read on other topics on this forum that many people kept this record number out of the POJO representing the data. Why is that? I feel more like putting it into my Vacation class...
- for the DBAccess implementation, I plan to construct if with a LockManager lockManager - concrete class - and a DataBase dataBase - an interface. Then in my main I would give a FileDataBase to it. Is it ok to have one interface and one concrete class there ? My justification is that the LockManager is unlikely to have multiple impls, whereas the DataBase might well...
- still for the DBAccess impl, why do some people provide their own interface there ? What's the added value and/or gotcha?
I'm planning to do SCJD in the near future, so I can't really help you at the moment. But I think others will agree by saying that you should not do anything that is not a must requirement. If the validation is not a must requirement for your assignment, then please consider if you really should implement that validation.
I will do the best I can to answer your questions.
1/ you want to use a value object (Vacation) in your data class. Why would you follow this approach? I guess all your methods from the interface you have to implement, contain String. So you will have to convert between Vacation and String, and maybe you are planning to implement a business layer which uses a value object too (so you have to convert once again).
I used String in my Data class, and used a value object in my business service and in the client. another advantage of just using String: if you opt for a dynamic approach (reading the database schema dynamically) it will be a lot easier to reuse your Data class for a similar database file which contains customers or hotels or ... and code reusability is a great advantage of any application
2/ in my business service (and client) I validate business rules, like for example "customer id must be 8 digit number". In my Data class I only do validations according to my database schema: number of fields in the String, the length of each field of the String, ... Of course the logic in the client and the business layer have to guarantee that the data is properly (correctly) delivered to the Data class. So this validation is not really necessary, but is an extra certainty that due to a bug the database file doesnot get corrupted! (and it's helpful for other developers using my Data class)
3/ i used as record number just a sequential incremented number, so record 1 in the database file has 0 as id,... I didn't add this value to the String (because String is a representation of a record is part of the database file) and the record number is not in the database file. That's also why the "deleted" flag is also not a part of the String. My value object contains fields for every element in the String + the record number.
4/ You design your Data class as you wish, you just have to meet the required "must" requirements (about the package, name of the class,...). I just had a singleton Data class approach, so just 1 class taking care of file access and locking.
5/ I was one of the people having their own interface (which extends the required interface). No gotcha's, lots of added values: you can add some own methods, like a specific find-method which returns Map<Integer, String> (instead of a int), so you can easily search for records: a combination of the original find-method with a read of every record number returned by the find-method