• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

URLyBird Thoughts about design and loosely coupling between Data and Room classes, etc.

 
Carlos Morillo
Ranch Hand
Posts: 221
Java Python Scala
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Everybody,


After my last post I've been questioning the design of my Data class implementing the DB interface provided by Sun.

Originally inspired by Andrew Monkhouse book I have a Room class the equivalent of the DVD class wrapping a String[] with a size of numberOfFields which is read
dynamically in the Data class with all the other schema elements and data records representing a hotel room.

Also currently in my Data class even though in many places in the implementation of the interface methods you have a String[] I create and manipulate Room objects
and internally in my Data class I have a cache of all the records read from the database file provided by Sun in a Map<Integer, Room>.

In the Monkhouse book which is a great starting point you also have in the DvdFileAccess class a lot of usage of the constants defined in the DVD class for the length of each field
element which is a component of the DVD class and objects.

It seems to me that there is some degree of coupling in the Monkhouse example.

I am leaning now to decrease and minimize the degree of coupling and knowledge of the Room class in my Data class
by strictly using a String[] in order to make it more generic and applicable to other possible domain problems.

I am also thinking of writing some static methods in a utility class to convert from Room to String[] and viceversa, and use
a Room where it makes sense and restrict the usage of String[] to the data class or whereever else where is needed when I have to use
the Data class API.

Does this sound reasonable and make sense?
Any thoughts?


Thanks in advance,


Carlos.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Carlos,

It all depends on what you want to achieve and what the major characteristics of your application should be.

If I have to name the 3 major characteristics of my application, I would say: simple code, code reusability and easy to extend.

Because I wanted code reusability I can't use a Room-object in my Data class (so just worked with String[]) and I also can't hardcode the database schema. So my Data class could be easily reused as a Data class for customers (if the database file has of course the same structure).

I chose the singleton pattern applied to the Data class (with a record cache) and marked every method synchronized. In my opinion the simplest approach possible. And because working with a String[] is not that easy (and also may lead to some hard-to-find bugs) I used in my RoomBusinessService and in the GUI Room-objects. And I have 2 static methods to do conversion.

I guess if I have to create a similar business service for customer management I'll be finished in less than 2 hours (gui not included), because I just have to create just a few extra classes and I am done.

Does this sound reasonable and make sense?
It sounds very reasonable and makes much more sense than your 1st approach (to me). So I would just say: go for it (and don't forget to document in your choices.txt why you introduced a Room-object instead of working with a String[], can't be hard to do).

Kind regards,
Roel
 
Vlad Djordan
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I can't use a Room-object in my Data class (so just worked with String[])


I did the exact same thing.

I chose the singleton pattern applied to the Data class (with a record cache) and marked every method synchronized.


Interesting. I suppose then you synchronized on the actual Data class then when providing concurrent access, ie.
locking on the entire database?



I made my Data class a Singleton as well, however, I lock on record numbers. I think even the Sun interface
defines the lock as: "Locks a record so that it can only be updated or deleted by this client."

Thus I've only synchronized my search and create methods, while the others will lock on the record number.
Both approaches work, and some of the tests I've run including some tests found here all execute properly.

I used in my RoomBusinessService and in the GUI Room-objects.


I plan to do the same, but have just finished the back end.


Vlad

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vlad Djordan wrote:I made my Data class a Singleton as well, however, I lock on record numbers. I think even the Sun interface
defines the lock as: "Locks a record so that it can only be updated or deleted by this client."

Thus I've only synchronized my search and create methods, while the others will lock on the record number.
Both approaches work, and some of the tests I've run including some tests found here all execute properly.
Just to ensure you have it spot-on (because your explanation is a bit unclear and it seems you have a wrong understanding) a few remarks. You have to consider 2 very important things when you are developing your Data class.

1/ You have to make sure your Data class is thread-safe (capable of handling multiple concurrent requests). I made my Data class thread-safe by applying the singleton design pattern and mark every method in Data class as synchronized (in my opinion the easiest approach possible). But you also could synchronize just blocks of code in every method, which makes your application more performant. By implementing this correctly your database file won't get corrupted.

2/ And then you have the lock and unlock method. The purpose of these methods are perfectly described in the ScjdFaq. In short: they prevent double bookings because 2 threads override each other's changes.

Could you verify if your Data class is handling both issues. When I want to update a record, I use this codeSo no synchronization on the data-instance just to lock/update/unlock (like you mentioned in your previous post). And that's why I think you are missing an important thing.

Kind regards,
Roel
 
Vlad Djordan
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roel,

I think I may have misunderstood your original post.

My create and search methods are method synchronized, while my lock, unlock, update, delete and read are block synchronized.

Of course when I update I have to first lock a record, update, then unlock, same for delete. I guess I went for performance by synchronizing
just blocks of code. My answer is yes and yes to both 1 and 2. The only two points I didn't follow in the provided interface are
throwing a DuplicateKeyException in create, and RecordNotFoundException in unlock, and I'll explain in the choices.txt why, but the
rest of the interface is implemented as is.

I've run a test available on the SCJD faq and all my runs completed successfully including incrementing the counter to the
limit of an int. I feel pretty confident about the design.

Thanks for checking up on me,

Vlad
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vlad Djordan wrote:I've run a test available on the SCJD faq and all my runs completed successfully including incrementing the counter to the
limit of an int.

Then you are good to go

Kind regards,
Roel
 
Consider Paul's rocket mass heater.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic