Please review my database design. I think I may have overdone it a little bit...so, need your valuable comments on it.
Some points before explaining my design: - No class in the design is a Singleton</br> - Dependencies are minimized/eliminated through the use of interfaces instead of concrete classes.</br> - Record number is the location of the actual record in the db.</br> - Deleted record numbers are kept in a seperate list in the RecordCache.</br> - all locking is done with the help of classes in the new Java concurrent package.</br> - Records are identified uniquely by their Contractor Name and Contractor Location pair. i.e. no records can have the same name and location pair. ----------- Design:
class Contractor implements IRecord - Instances of this class represent a record in the database.
Instances are sent back and forth between clients(network or not) and ContractorLogic.
Among other things, it has a method to generate a unique Key (ContractorKey implements IRecordKey) from the name and location values. RecordCache thus contains a map of key=recNum and value=IRecord pairs.
class Data.java - As required by assignment, class Data implements DB.
Data is a facade to subsystems, RecordCache and DataAccess.
Is not a singleton. The constructor at the time of creation of ONLY first instance will let the DataAccess subsystem load the data file and then the Data will load all the records into RecordCache.
Data also performs logical record locking.
Data doesn't know anything about the Contractor database. It's subsystems don't know about any specific database format such as Contractor either.
It and it's subsystems only deal with IRecord, IRecordKey and IRecordUtil (will come to IRecordUtil later.). IRecord is the interface that any entity wishing to be a record in the database should implement. Contractor.java is one such implementation of IRecord for B&S
<p> class ContractorLogic.java - This class is a bridge between the clients and the Data facade. This is a class that provides business methods to clients (network layer or direct access) and performs operations on Data objects.
Is not a singleton. Clients wishing to use the database services create a new instance of ContractorLogic for each request.
Each new instance of ContractorLogic deals with it's own Data instance.
Provides friendly methods to clients and let the clients pass Contractor objects to and from this class.
IMP**: While creating a new instance of Data, it passes a instance of ContractorUtil. This ContractorUtil implements IRecordUtil.
<p> class ContractorUtil implements IRecordUtil - This is a helper class that knows specifically about the Contractor (IRecord) object. [list-1]
The magic cookie for contractor database is stored in it and it provides helpful methods such as appending each record item with spaces as required, or transforming a bytearay into a Contractor record.
An instance of this IRecordUtil (ContractorUtil) is provided to the Data class during it's instantiation.
Data uses IRecordUtil to create a key from the passed in data array
Data uses IRecordUtil to format the data string array by appending required spaces to each column.
Data uses this IRecordUtil to determine if the record exists or not during the creation process and throw DuplicateRecordException if necessary.
As a overview, the Data facade and all it's subsystems do not require knowledge of any particular type of schema because the information about the Contractor record is passed through it via the utility methods of IRecordUtil. I would like to know whether this is a clean approach i.e. having to pass in a IRecordUtil helper instance to the Data, so that Data can use it to persist or read contractor info. ?
I can't think of any other method to make this approach more cleaner. Your comments/suggestion are very much appreciated.
Please let me know if you can't understand any of the above points and I can try to explain them again.