I implemented DBAccess interface in the Data class, as required by the instructions. It has all of its public methods synchronized. It's not the most performant solution but, since the instructions state that a simpler solution is preferred over a more complicated one, and since the native access to the file is probably single threaded anyway, I think it'll be fine. I just create an instance of Data in my code for a given Server, which has just one RandomAccessFile instance to access the underlying file.
My question is: should I prevent the (potentially disastrous for the database) creation of several instances of this class to access the same file, even if I don't do it in my own code? In other words, is it wrong if I rely on the (imaginary) programmer who would use these classes to avoid the creation of several instances of Data that point to the same file (by adding enough info about this fact to the Javadoc of that class)? Or should I prevent it by implementing a Singleton pattern or similar (which I don't like)?
As long as the DBAccess is not a singelton your synchronized, non-static methods are not a valid solution to prevent multi-access to database.
If two clients have each her own DBAccess object, both can call DBAccess to write the same record. The synchronized methods does what you have in your mind, if both clients use the same DBAccess object.
In my design, only one instance of Data is created per server (even if it's not Singleton at the moment). And, since just one Server is created in both network and standalone modes, I really have no problems with concurrent clients. It's effectively a Singleton, it just doesn't implement that pattern. And yes, a misuse of my Data class (several instances over the same file) could lead to database file corruption.
I don't like Singleton pattern much. And it gets uglier considering that I'm subclassing Data with URLyBirdData. Singleton and inheritance don't mix too well together. And it's quite limiting, because what happens if, in the future, the app needs to use several (different) database files? We would need to implement a "singleton per file" pattern, which is even uglier.
I've been searching the forum (I admit I should have done it before), and I see that I'm not the only one using this approach.
"1. I didn't make it a singleton. I have a business model class (BusinessServiceModel) that implements the business rules of the server and talks to the Data class. The Remote service (RMI) impl has an instance of this BusinessServiceModel to service any calls from clients. As there is only ever one instance of a remote server in the registry, there will only ever be one Data instance and one BusinesServiceModel instance, making it a singleton without needing code. The Data instance is kept for the lifetime of the BusinessServiceModel instance. Also to programatically make it a singleton means having extra public methods that aren't on the DBMain interface which isnt a good idea."
"I don't understand why so many people want to use Singleton for Data class. Is that any reason for that (except programmer mistake)? Isn't it too limiting? When some other/new version of application will have to use two different database files why it shouldn't be possible?
It looks to me like having (for example) RandomAccessFile as Singleton. Yes you can open same file with two instance of RandomAccessFile and if you will use it wrong way, your data will be corrupted. But it is not reason to have it a Singleton, is it?"
"I'll make a small attempt to answer, however. I would avoid making things static or singletons because it's not necessary. In the case of the assignment, you have another way to identify the database: You will most likely create a single instance of a server object (I use the term loosely to define which over object is responsible for creating the server socket for clients to connect to). This server object can have the DAO as an instance variable. You could just as easily create multiple instances of the server object, but that would make no sense. You have a single server, so just give it the DAO as an instance variable. No static or singletonness necessary."
But, then again, I don't know if this approach is valid.
There are alway several solutions for a problem. So your is one, if your requirements are full filled by your solution. As each solution there are (dis)advantage. You just have to explain in your choices.txt why you vote for your solution.
I know that there was one guy who passed the exam and had all methods with synchronized.
If your requirements do not tell you anything about synchronized, singelton, .. you are free to use or not use it.