aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Mark Spritzler/ Max H/Andrew Monkhouse: please comment on the holes in my design 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 "Mark Spritzler/ Max H/Andrew Monkhouse: please comment on the holes in my design" Watch "Mark Spritzler/ Max H/Andrew Monkhouse: please comment on the holes in my design" New topic
Author

Mark Spritzler/ Max H/Andrew Monkhouse: please comment on the holes in my design

Kim Barret
Greenhorn

Joined: Jul 21, 2003
Posts: 14
I have all the public methods of Data class in a DataAccess interface. My data class implements this interface. I have a LocalData class that has a data object (trying object composition here) to get local access.
For my remote data access, I have RemoteDataAccess interface that has the lock and unlock method signatures and it extends both Remote and DataAccess interfaces. There is a RemoteData class that extends UnicastRemoteObject and implements RemoteDataAccess and Unreferenced interfaces.
Now I have two options (from what I see): I could either copy and paste the code of public functions of RemoteData class (inherited from DataAccess interface) from Data class, since (correct me if I am wrong) the code for public functions doesn't change except for the Lock/unlock methods (that need to be implemented only for remote access). But this option is NOT good since we are replicating a lot of code which already exists.
The other option I have is data composition, I could have a Data object in my RemoteData class and call all the public methods of Data class from the respective public methods of RemoteData class (inherited from DataAccess interface). This doesn't require data replication of any existing data. I like this option but is this a good design? What are my other options? I am a newbie where design is concerned. Would appreciate some feedback and comments from ALL.
Svetlana Koshkina
Ranch Hand

Joined: Jul 08, 2003
Posts: 108
As far as i understood the requirements you can modify their Data class (modification over extention). In this respect your first option looks like modification of the original Data that you may not even use, just mention that you modified it and why. Sec. option looks more like an adapter design pattern. In my opinion you can use both as long as the program works.
I modified their Data class (slightly though: just changed those obsolete methods and added some additional static final var.) and then put it into much larger and functionally rich class. In short, i even did not use the original 'as is' and still feel very comfortable while waiting for submission results
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Hi Kim,
welcome to the 'Ranch. I like your second option. Why don't you think aloud a bit, and explore that one? I'll provide feedback if you like.
All best,
M


Java Regular Expressions
Kim Barret
Greenhorn

Joined: Jul 21, 2003
Posts: 14
Thanks for your response Max and Svetlana.
What I have done so far in my RemoteData class: I have a Data object in the RemoteData class which implements DataAccess interface (which has all the public method signatures of Data class). In my implementation of RemoteData class's public methods (inherited from DataAccess interface), I call respective public methods of Data class on the data object. I plan to implement the lock/unlock functionality in the RemoteData class.
I plan to use object composition for Local access also. I intend to have a LocalData class which shall have a Data object. Only this class won't have any need to implement the lock/unlock functionality and would be very straight forward. I could use the Data class directly but I prefer to have a separate class to implement the criteriaFind method because I don't think this method belongs in Data class.
I have modified Data class ONLY to get rid of the deprecated method calls.
I read your responses in other topics on lock/unlock functionality and have decided against a separate LockManager class. I plan to implement the lock/unlock functionality in the RemoteData class, itself. I have a static HashMap object to keep track of the Data object and the record number required to lock. Now each remote client gets a copy of their own RemoteData hence indirectly a copy of Data object. When the client requests to lock a record, I add the record number as key and client's data object as value to the static HashMap variable. This makes sure that when unlocking, only the client who locked the record should unlock it.
I am still working on the lock/unlock code. Would appreciate if you can point out any holes you see in the design or lock/unlock logic. Thanks.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

Like Max said the second option, which you have adopted is the best.
I am a little hesitant against your Static Hashmap in the DataAccess Remote class. But can't give any reasons why. Oh, wait, how again will you tell which client locked which record in that senario?
Good Luck
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
/*
Originally posted by Mark Spritzler:
Like Max said the second option, which you have adopted is the best.
I am a little hesitant against your Static Hashmap in the DataAccess Remote class. But can't give any reasons why. Oh, wait, how again will you tell which client locked which record in that senario?
Good Luck
Mark

She'll know which client locked which record, based on the fact the each client will have their own copy of DataAccess(which, in turn, will have it's own copy of Data).
Kim,
If I were you, I would simply stop right now, create a test space, and write a very simple proof-of-concept for your locking methodology. No need for File IO, just a lock/unlock, along with a "doStuff()" method. Then I would create some dozens of mock client threads to test it. You know, take your design for a test drive, kick the tires
btw, are you doing FBN?
All best,
M
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

"based on the fact the each client will have their own copy of DataAccess(which, in turn, will have it's own copy of Data). "
That's what I would be afraid of. Each client's own copy of DataAccess should have a reference to the one instance of Data on the server. So therefore, there are two problems. One Each client has its own Hashmap tracking their own locking, but has no idea as to any locks by any other client.
Mark
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Mark,
In Kim's design, each client has it's own Data instance(through having it's own DataAccess Instance): they are not sharing access to a single instance of Data on the server, as your statement implies

Each client's own copy of DataAccess should have a reference to the one instance of Data on the server.

Further, because the hashmap in Data is static, it will be shared by all instances of Data(lets focus on Data here, since it's a proxy for each DataAccess, which in turn is a proxy for each client: it'll lead to a cleaner discussion). Therefore, I think your second concern(below) is addressed.

One Each client has its own Hashmap tracking their own locking, but has no idea as to any locks by any other client.

This might be true if the hashmap were an instance variable, but it's not: it's static.
Basically, in this design, each Data object locks itself(Data.this) and the recordno it wants, into that static structure(the Map). This happens inside the Data.lock method. Thus, our concern that each client only has access to it's own lock evaoprates. Yes, each client is only tracking it's own lock, but it has access to the locks of all the other clients, because they are all inside the static map.
It's the same principle as the LockManager, which is also a Global structure that keeps all instances of Data. However, it's a bit more Object Oriented(IMO), because the Data class is taking responsibility for it's own locking. Also, it fits the SCJD's requirement that the lock method in Data be implemented. Finally, it avoids the extra code and complexity of having to write a LockManager in the first place.
True, it doesn't scale as easily as the LockManager, but I don't think that what Kim's concerned with here, and the SCJD doesn't grade on scalabilty: only clearity and simplicity.
Kim,
many people has earned perfect score with your design, so take heart. IMO, concentrate on implementing your proof of concept, and make sure you're comfortable with it.
M
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Kim, Mark and Max,
Max:
She'll know which client locked which record, based on the fact the each client will have their own copy of DataAccess(which, in turn, will have it's own copy of Data).

Mark:
That's what I would be afraid of. Each client's own copy of DataAccess should have a reference to the one instance of Data on the server. So therefore, there are two problems. One Each client has its own Hashmap tracking their own locking, but has no idea as to any locks by any other client.

Kim uses a static HashMap in Data, so the problem Mark points out (based on a misinterpretation of Max) cannot happen.

Kim:
... I have a static HashMap object to keep track of the Data object and the record number required to lock. Now each remote client gets a copy of their own RemoteData hence indirectly a copy of Data object. When the client requests to lock a record, I add the record number as key and client's data object as value to the static HashMap variable. This makes sure that when unlocking, only the client who locked the record should unlock it.

It seems OK to me as far as you are aware of - and accept - the fact that your design will never have to support multiple tables.
Best,
Phil.
[ August 27, 2003: Message edited by: Philippe Maquet ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Kim,
I think you are doing Fly By Night Services (since you mentioned the criteriaFind method).
Now since each connected client has it's own instance of the Data class, this means you will have to consider changing the add() method. If you leave it unchanged from what Sun provided, it will not work correctly in multi user mode.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Svetlana Koshkina
Ranch Hand

Joined: Jul 08, 2003
Posts: 108
I am already had a lot of jeebies and next of them will be all on you guys. In short, as far as i looked at locking mechanisns here, at the forum, they all were on high level - maps, vectors, remotes etc.
Where Holub's and Doug Lea's earthly semaphores went? Where everything takes care of itself - lock-unlock - hi: it still me - you are welcome | phh it's not you who locked it lets throw ex..n...?
Those that are on lower level are fitting just fine. Why nobody is mentioning it? Benefits: nonobtrusive, application-independent, compeletly encapsulate locking mech. without even thinking of identities that could be kept lined up neatly on some higher level. Huh? Just nervoius
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Max,
My reply crossed yours and I can see that didn't misinterpret anything.
Kim, what I wanted to point out about multiple tables is this : as you use a static HashMap (shared by all tables) with recNos as keys, your system would never support multiple tables. It's perfect because we have only one physical table to deal with, as far as you don't try in other parts of your db design to make it multi-tables (as I did) in which case your global db design would be inconsistent. Now if there is an issue here, you can solve it with a very little change : wrap the recNo in a Record class of your own (instead of a Long) and use Record instances as keys in your HashMap. It's just a few more lines of code :

Max
It's the same principle as the LockManager, which is also a Global structure that keeps all instances of Data. However, it's a bit more Object Oriented(IMO), because the Data class is taking responsibility for it's own locking. Also, it fits the SCJD's requirement that the lock method in Data be implemented. Finally, it avoids the extra code and complexity of having to write a LockManager in the first place.
True, it doesn't scale as easily as the LockManager, but I don't think that what Kim's concerned with here, and the SCJD doesn't grade on scalabilty: only clearity and simplicity.

I fully agree with you except for "Also, it fits the SCJD's requirement that the lock method in Data be implemented". To me, delegation == implementation.
Best,
Phil.
[ August 29, 2003: Message edited by: Philippe Maquet ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Svetlana,
Don't worry: just because we are concentrating on one design in this thread does not mean that other designs are wrong. It just happens to be a workable solution that the topic starter suggested.
If you would like to start a topic discussing something that is not regularly discussed here, I am sure everyone would be appreciative
Regards, Andrew
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Philippe Maquet:
Hi Max,
My reply crossed yours and I can see that didn't misinterpret anything.
Kim, what I wanted to point out about multiple tables is this : as you use a static HashMap (shared by all tables) with recNos as keys, your system would never support multiple tables. It's perfect because we have only one physical table to deal with, as far as you don't try in other parts of your db design to make it multi-tables (as I did) in which case your global db design would be inconsistent. Now if there is an issue here, you can solve it with a very little change : wrap the recNo in a Record class of your own (instead of a Long) and use Record instances as keys in your HashMap. It's just a few more lines of code :

Max
It's the same principle as the LockManager, which is also a Global structure that keeps all instances of Data. However, it's a bit more Object Oriented(IMO), because the Data class is taking responsibility for it's own locking. Also, it fits the SCJD's requirement that the lock method in Data be implemented. Finally, it avoids the extra code and complexity of having to write a LockManager in the first place.
True, it doesn't scale as easily as the LockManager, but I don't think that what Kim's concerned with here, and the SCJD doesn't grade on scalabilty: only clearity and simplicity.

I fully agree with you except for "Also, it fits the SCJD's requirement that the lock method in Data be implemented". To me, delegation == implementation.
Phil.

Absolutely. However, Mark's LockManager, as I understand it, sits outside of the Data class. It's not delegation at all. In the designs that Mark has advocated in the past, the lock/unlock methods are left un implemented.
M
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Max,
Max:
Absolutely. However, Mark's LockManager, as I understand it, sits outside of the Data class. It's not delegation at all. In the designs that Mark has advocated in the past, the lock/unlock methods are left un implemented.

My own design is this :

Do you agree with it ?
Best,
Phil.
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
I think it works, and I like the idea of encompassing the locking inside of of Data. however, you don't really need to support multiple tables, so I'm not sure that would have implemented it yet: I might have just mentioned that it was possible to do so, and left it at that.
One question: that does Table do?
M
Ian Roberts
Ranch Hand

Joined: Aug 20, 2003
Posts: 46
Kim and Max,
Its nice to see that other people are applying and agreeing with the same design that I am implementing! I followed the threads on the large debate concerning the use of a LockManager but cannot bring myself to go against my OOAD training and what appears to be Sun's instructions.

The design Kim has suggested is very, very close to the one I propose to put forward, probably with the exception of the new class names!
Andrew, who has been a great help, has made a good point concerning the recordCount and it does appear that the add() method will require updating to avoid some nasty surprises.
How are you proposing to handle the recordCount issue? A question I asked on my thread was whether or not changing the recordCount to a static member variable would violate Sun's instructions but I think that the class has to change regardless of whichever locking mechanism is deployed and was probably deliberately done that way to make the assignee make the decision and to record why. What do you think?
Cheers,
Ian R.
Kim Barret
Greenhorn

Joined: Jul 21, 2003
Posts: 14
Thanks for your responses Max, Svetlana, Mark, Andrew and Phil.
I am discussing these ideas as I implement the logic and this discussion here brought to light many issues I wasn't even aware of.
Thanks Phil for the code example. I was planning a similar approach regarding the record number being stored in the HashMap as an object so that multiple databases are possible with my assignment implementation. Just to clear up a doubt though, when you talk about "multiple tables" - I am assuming you are talking about multiple databases. Am I right?
Phil, the reason I am implementing my lock/unlock functionality via a static HashMap is because its fairly simple to understand. There is no need for a separate LockManager, there is no need to make or use Data as a singleton to ensure that all remote clients use the same Database. Is this not reason enough to take this approach? I am asking this because apparently in your documentation you used weak references and reference ques as additional justification along with the simplicity of this approach.
Phil, when you say "I had to play with WeakReferences stored in a regular HashMap, with a ReferenceQueue", you mean in your implementation you wrapped the Data and Record objects as WeakReference objects and used WeakReference queues? Why would you do that? In addition to added complexity to code, isn't using WeakReference for our case a little risky?
From my understanding of WeakReference (correct me if I am wrong - don't know much abt this) - "a WeakReference object can be collected by the garbage collector if no OTHER part of the program is using that object, since we could always retrieve that object from permanent storage" - doesn't this mean that while our WeakReference object is in the HashMap if no OTHER part of our program is using that object, the object would be garbage collected (even if JVM is NOT running low on memory). This requires us to add additional code to first check if the WeakReference object has been garbage collected and if it has, than retrieve it from database file. Now what if both the key and the value are garbage collected? Maybe my understanding of this package is faulty. Would appreciate it if you could throw some light on it. Thanks.
Max: "True, it doesn't scale as easily as the LockManager, but I don't think that what Kim's concerned with here, and the SCJD doesn't grade on scalabilty: only clearity and simplicity."
Max, how is this approach not scalable? You are right I had not thought about the scalability issues here.
Max: "Absolutely. However, Mark's LockManager, as I understand it, sits outside of the Data class. It's not delegation at all. In the designs that Mark has advocated in the past, the lock/unlock methods are left un implemented."
Max, I leave the lock/unlock methods provided in the Data class provided by Sun M. unimplemented too! For my remote data access, I have RemoteDataAccess interface that has the lock and unlock method signatures and it extends both Remote and DataAccess interfaces (where DataAccess interface has all the public methods of Data class except the lock unlock methods). There is a RemoteData class that extends UnicastRemoteObject and implements RemoteDataAccess and Unreferenced interfaces. It is in this RemoteData class that I am implementing the lock/unlock methods! Am I correct in understanding from your statement Max that the lock/unlock methods should be implemented in the Data class and in my RemoteData class simply use these methods where as in my LocalData class NOT use them?
Andrew, yes I am doing the FBN assignment.
Andrew: "Now since each connected client has it's own instance of the Data class, this means you will have to consider changing the add() method. If you leave it unchanged from what Sun provided, it will not work correctly in multi user mode."
Andrew, I guess what you are saying is I would have to either synchronize or lock the database and let only one client add records to the database at a time? In that you are right, I would have to take into consideration that multiple people might want to add records to the database concurrently.
Thanks all very much.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Kim,
Just to clear up a doubt though, when you talk about "multiple tables" - I am assuming you are talking about multiple databases. Am I right?

Yes, multiple physical database files.
Phil, the reason I am implementing my lock/unlock functionality via a static HashMap is because its fairly simple to understand. There is no need for a separate LockManager, there is no need to make or use Data as a singleton to ensure that all remote clients use the same Database. Is this not reason enough to take this approach?

Yes, your design is OK and simple which is a quality. Don't change anything to it IMO.
Phil, when you say "I had to play with WeakReferences stored in a regular HashMap, with a ReferenceQueue", you mean in your implementation you wrapped the Data and Record objects as WeakReference objects and used WeakReference queues?

No, but it was not a good idea anyway. Don't get influenced by it.
In my DBAccess interface lock methods are included. Not the case in your assignment ?
Am I correct in understanding from your statement Max that the lock/unlock methods should be implemented in the Data class and in my RemoteData class simply use these methods where as in my LocalData class NOT use them?

I feel it's better. Your LocalData may even use them, it's not an issue IMO.
Best,
Phil.
[ August 29, 2003: Message edited by: Philippe Maquet ]
Kim Barret
Greenhorn

Joined: Jul 21, 2003
Posts: 14
Phil:
How are you proposing to handle the recordCount issue? A question I asked on my thread was whether or not changing the recordCount to a static member variable would violate Sun's instructions but I think that the class has to change regardless of whichever locking mechanism is deployed and was probably deliberately done that way to make the assignee make the decision and to record why. What do you think?

I thought since the add method is synchronized, there would be no problem there. Why do we need additional handling here?
Phil:
In my DBAccess interface lock methods are included. Not the case in your assignment ?

The way I thought about it was: lock/unlock are functionalities not required in the local access hence my DataAccess interface had all public methods of Data class with the exception of lock/unlock public methods. I have a RemoteDataAccess interface which has lock/unlock public method signatures and my RemoteData class implements this interface and implements these methods.
But the more I think of it, the more I like your suggestion Phil. I think I should implement the lock/unlock methods in Data class and use them from RemoteData class and not use them for LocalAccess, since anyways I am using object composition and Adapter pattern rather than extending the data class to use its methods for Local and Remote access. Would appreciate it if you could point out issues I am overlooking here, in this approach. Thanks.
What does everyone think of this approach?
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Ian Roberts:
Kim and Max,
Its nice to see that other people are applying and agreeing with the same design that I am implementing! I followed the threads on the large debate concerning the use of a LockManager but cannot bring myself to go against my OOAD training and what appears to be Sun's instructions.

The design Kim has suggested is very, very close to the one I propose to put forward, probably with the exception of the new class names!
Andrew, who has been a great help, has made a good point concerning the recordCount and it does appear that the add() method will require updating to avoid some nasty surprises.
How are you proposing to handle the recordCount issue? A question I asked on my thread was whether or not changing the recordCount to a static member variable would violate Sun's instructions but I think that the class has to change regardless of whichever locking mechanism is deployed and was probably deliberately done that way to make the assignee make the decision and to record why. What do you think?
Cheers,
Ian R.


Hi Ian,
I have to agree with you: recordCount needs to become accurate if you want to implement add/remove. Maybe making it static is the answer, maybe make a call to a (new) private method called getRecoundCount which actually checks the File size, etc.
However, I don't really think you need to implement it: since your GUI clients can't add or remove records, and since the instructions say the Data class is 'complete' except for locking and the depreciated methods, I think you can leave it be. Honestly, I think it's just an oversight on Sun's part, and I doubt they would blame you for it.
Al best,
M
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Max,
However, I don't really think you need to implement it: since your GUI clients can't add or remove records, and since the instructions say the Data class is 'complete' except for locking and the depreciated methods, I think you can leave it be. Honestly, I think it's just an oversight on Sun's part, and I doubt they would blame you for it.

However since FBNS requires the add() and delete() methods to be available to networked clients (regardless of whether our client uses them), then as a bare minimum you would have to have a major comment in your javadoc saying that this method is not going to work in multi user mode. And my question would then be - why are we making a method available that we know won't work? IMHO it is better to spend the time fixing the issues.
Regards, Andrew
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Kim,
You wrote :

Phil:
quote:
--------------------------------------------------------------------------------
How are you proposing to handle the recordCount issue? A question I asked on my thread was whether or not changing the recordCount to a static member variable would violate Sun's instructions but I think that the class has to change regardless of whichever locking mechanism is deployed and was probably deliberately done that way to make the assignee make the decision and to record why. What do you think?
--------------------------------------------------------------------------------
I thought since the add method is synchronized, there would be no problem there. Why do we need additional handling here?

The question was asked by Ian, not me. I have quite different instructions than yours (URLyBird 1.2.1), and no recordCount issue in mine, so I cannot help you here.
I think I should implement the lock/unlock methods in Data class and use them from RemoteData class and not use them for LocalAccess, since anyways I am using object composition and Adapter pattern rather than extending the data class to use its methods for Local and Remote access. Would appreciate it if you could point out issues I am overlooking here, in this approach

It seems perfect to me.
Best,
Phil.
Qusay Jaafar
Ranch Hand

Joined: May 06, 2002
Posts: 127
Your design has many similarities with mine.
I used DataAdapter which implements DataInterface.
I coded criteriaFind() method inside DataAdapter.
I didn't modify Data class except for deprecated methods.
I used RMI Factory to get a unique connection object.
I implemented lock\unlock methods inside RemoteData which also implements Unreferenced interface.
I used static HashMap to identify clients [hashMap.put(recordNumber, this)].
WeakHashMap will not work if memory still low. Garbage Collector will not start here.
I didn't modify add() method becasue once I read this method is a part of an old assignment which needs to use add() method.
Now, my concern is about using DataAdapter. It is a nice idea to use it but isn't DataAdapter will give another decoupling layer that no need to use it??? :roll:
How you handle the exception especially DataInterface will throw RemoteException. (LocalAccess will use DataInterface) that's mean client need to throw a RemoteException which is not a good idea. I handle it by throwing IOException in client side. is this the right approach?
How you handle (db.db) location? is it by hard code the entire path which is not a good idea?
By the way, I did the test for lock()\unlock() methods and even when a crashed client, everything was going fine.


Qusay
Qusay Jaafar
Ranch Hand

Joined: May 06, 2002
Posts: 127
Any idea
Bharat Ruparel
Ranch Hand

Joined: Jul 30, 2003
Posts: 493
Hello Qusay,
You wrote:

Now, my concern is about using DataAdapter. It is a nice idea to use it but isn't DataAdapter will give another decoupling layer that no need to use it???

On the contrary, I think that DataAdapter class is necessary for the following reasons:
1. It allows you to pretty much use the same code on the server end for the "alone" and "network" modes since the connection object can hide these details from the client.
2. It allows you to tailer your business exceptions appropriately and chain them upwards to the GUI client so that it can display meaningful and user-friendly messages.
Max's book has a nice discussion on the benifits of a DataAdapter class. I am not sure why you are having second thoughts on this. I am using it. Are you worried about a convoluted flow of calls? If so, define for yourself, what are the responsibilities of each class and the answers will begin to emerge.
Hope this helps.
Regards.
Bharat


SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by Andrew Monkhouse:
Hi Max,

However since FBNS requires the add() and delete() methods to be available to networked clients (regardless of whether our client uses them), then as a bare minimum you would have to have a major comment in your javadoc saying that this method is not going to work in multi user mode. And my question would then be - why are we making a method available that we know won't work? IMHO it is better to spend the time fixing the issues.
Regards, Andrew

I agree, this is problematic. My best interpretation is that, since the assignment asserts that the Data class in FBNS is 'complete' except for the locking/unlocking and deprecated methods, then I take the assignment at it's word. I don't think you can be faulted for that, and it's the best of least work, so I like it
M
ghanshyam sharma
Greenhorn

Joined: Jan 05, 2003
Posts: 24
Very interesting discussion guys thanks for stimulating my brain.
I would like to make a few comments about my implementation, may be it beings up new ideas or maybe it exposes some holes in my implementation.
I have fully implemented add() [createRecord() in my assignment], I have introduced a new method called lockNewRecord() which is internally used by the implementation class to generate the next available record number and lock it for record creation. This way no other creation can interfere with a particular record creation. Although the GUI doesnot use this method but SUN SPEC says we have to implement it so I did.
I have not implemented the file level code in the Data class itself. I have a DataHelper class which has the low level code for everything, and then the Data class calls the methods from this class. Also all Record Locking code lies in the LockManager class and the Data class delegates locking to LockManager class. The reason for this design is that I do not want the Data class to have too much code, whic will create difficulty in maintenance, and also OOAD techniques support seperation of functionality into cohesive units [I got a 97 is SCEA , but am unsure of my approach here since sun instructions are rather vague ].
Although I am a bit doubtfull about not using lock unlock functionality in the local mode !!! If you think from a futuristic point of view, any functionality addition on the server side will have a big problem if we do not use locking. In the future we may need to henhance our design for various reasons [after all we all implementing a database syste !!!] we may need parallel implementation of things which may screw up due to lack of locking ??? Does my reasoning sound overkill.
In locks I define a lock with a record number and a timestamp and is stored in the hashtable with a key = a very unique cookie generated from a helper class. I can always enhance lock class to include table names to provide acces to multiple tables, so my design is okay as far as future enhancement is concerned ...Any comments here ???
I will write more as more issues cross my mind.
-Sharma


Sun Certified Enterprise Architect<br />Sun Certified Java Developer<br />Sun Certified Java 2 Programmer<br />IBM OOAD using UML<br />IBM XML and Related Technologies<br />BEA Certified WebLogic Developer (6/7)
ghanshyam sharma
Greenhorn

Joined: Jan 05, 2003
Posts: 24
Also I am planning to build a lock expiration mechanism but am unsure as to how ??? Using WeakHashMap doesn't sound like a simple idea. I am trying to build a lazy expiration where a lock expires if not used for a given time interval + now the record is required by another client . I guess my decision to delegate locking to a seperate LockManager is going to help me here since It would avoid the Data class code getting too complex ??? Dont know if I am missing something here :roll:
-Sharma
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Sharma,
I have fully implemented add()....

That sounds good to me.
I have not implemented the file level code in the Data class itself.

Also very nice.
but am unsure of my approach here since sun instructions are rather vague

Deliberately vague
The SCJD is not just a test of how well you can program, but also a test of how well you can interpret vague (and sometimes contradictory) specifications and justify what you have done.
It sounds like you are thinking your issues through very well. As long as you are also putting these comments into your design decisions document, you should get an equally high mark for this certification.
Although I am a bit doubtfull about not using lock unlock functionality in the local mode !

My usual comment here is: why not use locking in local mode? So far no one has given me a (IMHO) good reason not to use it. The best reason that anyone has given is that the locking is redundant.
If you look at the reasons for using locking: it means that you are always using the same code for both local and remote modes, you have less code to maintain, and it is more extensible later - then I think that local locking is a good idea.
In locks I define a lock with a record number and a timestamp and is stored in the hashtable with a key

Is the timestamp the key? If so, then there might be room for concern.
Also I am planning to build a lock expiration mechanism but am unsure as to how ?

This is a very nice idea, however I believe it is outside specifications. You will have to check your own specifications to be sure.
Using WeakHashMap doesn't sound like a simple idea.

Don't let Max hear you say that
I think you are talking about WeakHashMap for when your client disconnects (or crashes) without releasing it's locks (I don't think it works well in a timeout scenario). In which case, if you are using RMI, you could also look at the Unreferenced interface.
I am trying to build a lazy expiration where a lock expires if not used for a given time interval

But what happens to the client that now believes it has the lock? You cannot notify it that the lock has expired. So do you just ignore the issue, then when the original client tries to do something with the lock you then throw an exception? This is achievable - it will need to be well documented though.
Regards, Andrew
ghanshyam sharma
Greenhorn

Joined: Jan 05, 2003
Posts: 24
Thanks a Lot Andrew. I very much appreciate your detailed response. Guys like you make this forum real productive.

Well I agree on your coments on using locks in local mode too. Infact thats how I have already build and justified my implementation.
The timestamp is not a key. The timestamp is just a way to keep track of the locks creation or AGE. I have a seperate utility class which generate unique long numbers (Required as cookies in my assignment ) which keep track of the clients. So that part is not a concern. I wanted to clearely define the expiration interval using a default value of maybe 30 seconds which can be overriden using a value from a properties file. Using lazy removal of expired locks from the hash table is a rather very simple process and I have already implemented and tested it successfully. The only concern left is throwing the right message to the client whoes lock is expired but who still want to do something with that lock. Right now he just gets a illegal access exception, but If I wan to give him a very accurate error message including his lock expiration, I will have to add some more code. [This goes towards an overkill I guess !!!]
It is not required by my assignment but I dont know how can you implement a locking solution without a lock expiration strategy, and I am just going for the best that I can think of.
Another thing I am not very comfortable about is using Combo Boxes for search fields. In commercial solutions search fields seldom use combo boxes [or am i a morone ???] If the JTable is already displaying all records when the applications starts, why do we need to use combo boxes for search.
-Sharma
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11460
    
  94

Hi Sharma,
It is not required by my assignment but I dont know how can you implement a locking solution without a lock expiration strategy, and I am just going for the best that I can think of.

Well there are lots of things that get mentioned from time to time as being esential in a real life application. However they are not required for this assignment. It does seem that people who do simple solutions do get very good marks. There was one person recently who had a very simple locking solution for which they got 100%.
Another thing I am not very comfortable about is using Combo Boxes for search fields. In commercial solutions search fields seldom use combo boxes

Whether a current commercial solution uses a combo box or not does seem to vary. Many flight booking web solutions seem to use combo boxes. I would imagine that as more other forms of reservation systems become web enabled that we will see more combo boxes.
If the JTable is already displaying all records when the applications starts, why do we need to use combo boxes for search.

The person could still make a typing mistake even when they can see the original on the screen in front of them.
Also if they were going from one search result to a different search result, then they won't have the luxury of having the records in front of them (currently displaying all records for "Smallville", next search, all records for "Metropolis" - because we are displaying Smallville records, we cannot see Metropolis to determine how to spell it).
Regards, Andrew
ghanshyam sharma
Greenhorn

Joined: Jan 05, 2003
Posts: 24
Hmm, I would say you convinced me into using combo boxes for the search fields... Thanks a lot dude...
Too bad I cant put a tool tip saying "Dedicated to Andrew" when the customer crosses over my combos Just kidding... I appreciate your detailed responses very much.
-Sharma
 
wood burning stoves
 
subject: Mark Spritzler/ Max H/Andrew Monkhouse: please comment on the holes in my design