aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Certain Points to ponder Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Certain Points to ponder" Watch "Certain Points to ponder" New topic
Author

Certain Points to ponder

Kevin Broderick
Ranch Hand

Joined: Jul 19, 2009
Posts: 39
Hody,

I would like to get ye fellow ranchers your thoughs on the following points.

I'm cashing the file into an ArrayList and to delete a record the first field is set from 1 to 0. However at some point there will be a call to readRecord where the Jtable will need to be populated and if it come across a record position that has been set to 0 it will throw a RecordNotFoundException. So to get around this problem I'll create a service class that will query Data for a list of active records and Jtable will traverse with this list getting an active record each time from readRecord.

CreateRecord will add a new record to the table and return the record position on that table. If it fails to create a new record then maybe it could return -1 to denote a failed attempt. Maybe not because its simply not a good idea to use a return type for error flaging.

Should all method in Data be synchronized especailly if Data is to be a Singleton?

My fellow ranchers, thanks

Kevin
Vlad Djordan
Greenhorn

Joined: Jan 15, 2010
Posts: 15
Hi,

I'm cashing the file into an ArrayList and to delete a record the first field is set from 1 to 0. However at some point there will be a call to readRecord where the Jtable will need to be populated and if it come across a record position that has been set to 0 it will throw a RecordNotFoundException. So to get around this problem I'll create a service class that will query Data for a list of active records and Jtable will traverse with this list getting an active record each time from readRecord.


Some drawbacks about using a List instead of a Map to cache records you can read about here. I'm not sure exactly what you mean by setting the first field from 1 to 0? What happens if you delete 10 records, how is this handled by your list? My map contains record numbers as keys, and Room objects as values which are built using RoomColumn data. Then when I 'delete', I set the value of a key-value pair to null, and later can reuse that space when creating new records.

If it fails to create a new record then maybe it could return -1 to denote a failed attempt.


I would strongly suggest against doing this. In fact, I don't believe it is necessary given the scope of the assignment. I don't handle this situation. The only exceptional circumstance that should happen (if your assignment is similar to mine where the create method is declared with the DuplicateKeyException) is to throw the DuplicateKeyException. By the way, I don't handle this scenario either and I will explain in my choices.txt why.

Should all method in Data be synchronized especially if Data is to be a Singleton?


Many have taken this approach, and it is perfectly valid and if done right, you will not get penalized and can receive maximum marks on the locking section. Personally, I had a different approach in mind, and as soon as I finished the code in my Data class, the locking worked. I method synchronize only create and find methods, but my lock, unlock, read, update and delete are block synchronized.

There's some very good tests available for your locking mechanism, once you are finished, here and here.

Cheers,

Vlad
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5201
    
  12

Hi Kevin,

1/ use of ArrayList: I totally agree with Vlad and suggest not using this collection for your record cache. You should certainly read the link he provided, contains a lot of valuable information and I think it certainly will convince you to follow another approach

2/ returning -1: I agree again with Vlad. First of all it is not required, so just stick to the requirements of the assignment (extras won't be rewarded, so might only result in point loss). Secondly when you use a record cache I can't think of a scenario where a record can not be added (besides an OutOfMemoryError).

3/ for making your Data class thread safe there are several possibilities. one of them is the singleton data class and marking all methods synchronized. But that is not required, but you can certainly pass with this approach, considered to be the easiest one (I passed with it). But it is your own decision, there is just 1 requirement: your Data class must be thread-safe and able to handle multiple concurrent requests

Kind regards,
Roel


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
Kevin Broderick
Ranch Hand

Joined: Jul 19, 2009
Posts: 39
Hody Ranchers,

So far so good, my data class is comming along fine. I have synchronized all methods and credit to Roberto's test my locking and unlocking seems to prevent deadlock. But now I am stuck.

I made the Data class a Singelton and the Data class is going to work with the file access, but now I cannot pass a db file and path name through it constructor. Would the solution here be to not make Data a singelton but keep all methods of Data synchroized?

Another point: I'm using a Hashmap to cash the data and I'm treating the recNo as a string. Is there anything wrong with this? should I make the key value a Long type?

In update and delete methods, I'm thinking of not throwing RecordNotFound exception because I have make the lock method to ensure that the data does exist or else it does not lock and it throws the RecordNotFound exception thus the method calling lock does not proceed with Update/Delete.

Final point: I'm thinking of making a file access class for data but Data itself is to controll the locking mechanism. Its not a complete Facade so what pattern would it be?

And fellow Ranchers, thank you very much

Kevin
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2264
    
    3

Howdy, Kevin!

I have synchronized all methods and credit to Roberto's test my locking and unlocking seems to prevent deadlock.


Alright!

I made the Data class a Singelton and the Data class is going to work with the file access, but now I cannot pass a db file and path name through it constructor. Would the solution here be to not make Data a singelton but keep all methods of Data synchroized?


Champ, how about having something like this:



Another point: I'm using a Hashmap to cash the data and I'm treating the recNo as a string. Is there anything wrong with this? should I make the key value a Long type?


I'd say that the natural thing to do would be to use the type that is expected in the methods of the interface provided by Sun. For instance, if your read() method expects a long, then go for a Long.

In update and delete methods, I'm thinking of not throwing RecordNotFound exception because I have make the lock method to ensure that the data does exist or else it does not lock and it throws the RecordNotFound exception thus the method calling lock does not proceed with Update/Delete.


If I make no mistake, Roel also took this approach. If the record is not locked, you can throw an IllegalStateException.

Final point: I'm thinking of making a file access class for data but Data itself is to controll the locking mechanism. Its not a complete Facade so what pattern would it be?


Hum... maybe Semi-Fa├žade? I guess no patterns would be applied then...


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Matteo Palmieri
Greenhorn

Joined: Sep 09, 2008
Posts: 28
I made the Data class a Singelton and the Data class is going to work with the file access, but now I cannot pass a db file and path name through it constructor. Would the solution here be to not make Data a singelton but keep all methods of Data synchroized?


This is an interesting question I've been asking myself several times. The solution proposed by Roberto is good, but there are several cases where the getInstance with parameters requires special exception handling code that would be a burden to replicate in every piece of code where this method is called. Furthermore it usually happens that the part of the application where the singleton is actually instantiated (the first time is used) is known at compile time so it would make sense to limit the parameter passing and exception handling to this piece of code.
I faced this situation by implementing a slight deviation to the singleton pattern as documented below. I'd like to get your opinions about that.


SCJP1.4: 96% SCWCD5: 91%
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5201
    
  12

Hi Kevin,

I will add 3 things:

1/ I have the same approach as you (singleton and all methods synchronized that is) and unlike Roberto I just have one getInstance method. How do I pass the database path to the Data class? I don't, I just guess it Seriously, I added 2 methods to my own interface (which extends Sun's): 1 method to initialize the Data class which takes a parameter containing the database path (create my record cache) and 1 method to "end" the Data class (write records from record cache back to file). If you call a method without first having called the initialize-method an IllegalStateException is thrown.

2/ Totally agree with Roberto about HashMap and Long

3/ I'm happy to see someone else noticed that the RNFE in update/delete/unlock is redundant. You first have to lock the method and if it doesn't exist the RNFE is thrown here, but it can't happen later on (if you implemented the locking/unlocking of the records correctly of course). So I even redeclared (overrode) these methodes in my own interface and didn't add the throws clause:
Advantage: it makes more sense and because the unlock-method doesn't throws a RNFE anymore you don't have to clutter your code with a catch in the finally-clause.

Kind regards,
Roel
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2264
    
    3

Matteo Palmieri wrote:The solution proposed by Roberto is good...


You mean, in the code posted above, right? Well, I forgot to include in the code that the getInstance(String) method may throw DatabaseException, and the other exceptions may extend it (RecordNotFoundException, DuplicateKeyException and others you may want to create).

You know, recently I wrote an article about the SCJD, and I coded/thought again about the solution and everything... indeed, I created 2 getInstance methods... but it isn't really necessary. When the application starts, the Data class can be initialized and passed to the business object (a dependency injection via constructor). The business object holds an instance of the Data class and is passed to the window object, which uses the business object in the ActionListeners, for instance. The objects are passed to each other via constructor, which characterizes dependency injection. After I read POJOs In Action, I now always ask myself the following question: is this object's responsibility to handle this other object's life cycle? And No is the answer most of the time... so a good idea is to pass the objects to each other via constructor.

This way, only one getInstance(String) is necessary in the Data class.
Kevin Broderick
Ranch Hand

Joined: Jul 19, 2009
Posts: 39
Thanks Guys Your help is terrific. I made a New Years resolution to get this completed for once and for all and your help is helping to accelerate the progress
 
Consider Paul's rocket mass heater.
 
subject: Certain Points to ponder