• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

B&S Database Design Structure

 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

I am doing the B&S SCJD exam at the moment. I am now at a stage where I have a draft version of my Data class as specified by the interface given to me in the assignment:



I have also created a class named DataAdapter with the following Methods (among others):



My bookRecord/unbookRecord methods in the DataAdapter Class are basically lock, update, unlock sequences.

My Data class maintains a HashMap of lockedRecords and lockRecord and unlock in the Data class add and remove record numbers from this HashMap respectively. None of the methods in Data are marked as synchronized however the Create, Update and Delete methods in Data synchronize on the lockedRecords HashMap before checking if the record they are seeking to modify is locked with the correct cookie, and then modifying the record.

I am trying to take stock of my design now before proceeding any further. Despite reading for days on this forum and other external links given in this forum I am still not clear how to proceed. My original inclination was to make Data a singleton (private constructor with getSingeltonInstace() method) which certainly sounds attractive at first. My initial thoughts were to create a DataAdapter instance per client, and have every DataAdapter instance fetch the Data Singleton.

However after extended reading here and elsewhere I believe the Singleton pattern is not needed and should not be used in terms of good practice.

I think one of the attractive things about Singleton for us novices to concurrency is that it keeps things simple and provides a manageable way to think about things. I still am confused when I try to consider the possibilities with Data not a Singleton. I appreciate this forum is not in place to gift-wrap solutions for us, but I think the most important thing you all could help me with is asking myself the right questions to try to progress!

I am interested in whether making the Data Class a multiton (allowing one instance of Data per db file specified by the client) or whether having no control on the instantiation of the Data class (at the level of Data and DataAdapter - maybe control can be placed on the instantiation of the Data Class in the RMI layer - does anyone have any experience with this possibility, if it exists?) is a 'better' solution. By better I mean aiding concurrency but keeping the whole thing thread safe without having to tac on anything that is not strictly required (like I know people have passed without a seperate lockManager Class)

I would like to keep my management of locks simple, so I'd like to stick with a Collection of locked records, but moving Data away from a Singleton raises the question of should this collection be static or should it be an instance member of Data? If I was doing a multiton Data Class with one instance per db file as specified by the client I would need one HashMap per db file also - I find it hard to think how to implement that?

If it is viable to put no control on the instantiation of the Data Class in the Data Class itself how can a collection of lockedRecords be maintained that is 'global' per db-file?

Your replies will be very much appreciated

Czarak
[ September 21, 2005: Message edited by: Czarak Ynehac ]
 
Ranch Hand
Posts: 237
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Czarak Ynehac:
singleton (private constructor with getSingeltonInstace() method)



Respectful Suggestion: do not lack a public no-arg constructor in any of your classes for the SCJD. Reason 1: some test methods expect to subclass or otherwise use the public no-arg constructor of any class to be tested. Reason 2: someone in this forum (long ago) reported receiving an automatic failure along with some feedback identifying a lack of an explicit public constructor somewhere; a generated default constructor does not accomplish exactly the same results at some point in development (compilation thru testing). Why not use the Singleton concept without strict adherance to the full design pattern? Hoping this is useful info ...
 
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there,
I agree with you Czarak, having a single instance of Data class should be the responsibility of the application rather than the class its self, if you think of it further, Data class represents a resource, and naturally, programs can request as many needed resources as they wish "a program may choose to open multiple database files". In other words, in normal circumstances having multiple intances of Data should be fine, "but" within the context of our assignment this is crucial. Therefore, I ensured that there is a single instance throughout the execution of my application by implementing a mediator class "App" that manages all resources:



where App will return the same Data reference all the time.

I had the same worrys regarding the Automated Software test. And I thought about whether this test "harness" will attempt to access the Data class. As a result, I posted a question regarding this and Andrew had this valuable remark:

As a side note: it is my understanding that Sun do not have a test harness (yes, I do know that this contradicts what they say in their instructions). They do have automated tests that will confirm basic structure of your submission / method signatures of specified interfaces and classes, but that is as far as it goes. There has been some speculation that a test harness was too difficult to generate since Sun have not specified a constructor for the Data class (and there are many different constructors possible).



"However, confirming this from Sun doesn't hurt."

I don't see where a default constructor can fit in the Data class implementation, as I mentioned above this class represents a resource "Data class wrap a DB file", the following line is illogical, that's why this constructor doesn't exists in the API:




These are only thoughts, hope to here your comments soon.

Hatim
 
Czarak Ynehac
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi John, Hatim,

Thank you for your responses!

John, I'm afraid I would dismiss your suggestion on the grounds that:

A) Sun put no Must requirement (in my exam) on the constructor of the Data class therefore they cannot tie a test harness to a particular implementation of this constructor.

B) Many people seem to pass with Data as a true singleton.

C) Andrew's quote which I had previously read and which Hatim helpfully quoted above.

Also, the thurst of my post was a desire to move away from creating Data as a Singleton, so in the context of this thread I think this is a moot point.

Hatim, I don't fully understand your approach but it does interest me. I have read a little on the Mediator Pattern before, but again I was convinced that it was overkill for the SCJD project. I'm trying to constantly keep in the back of my head that it is very easy to fall into the trap of over-engineering for this project. I would like to do the minimum amount of code/complexity in keeping with the spirit of the exam.

If anyone else has some comments on my original post I would love to hear them! Particularily about how (or where in the overall application) to control instantiation of the Data Class and then depending on how you control instantiation of the Data Class how do you co-ordinate a collection of locked records between these multiple instances of Data? The issue of clients instantiating Data with differet DB files is further confusing me. If we thought about all clients only using one DB file then one static collection in the Data class would suffice to track locked records across multiple instances of Data, but what about when there are multiple instances of data looking at multiple DBs?

Andrew, in the absence of your forthcoming publication I don't feel too guilty in asking if you could put any more shape on my thinking regarding these issues?

I work for a large multinational with many newly recruited graduates who will all be taking SCJD over the next 18 months and I am very envious of them that they will have your book for guidance Andrew

Czarak
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If I understood your question here is what I believe:
1) Do your singleton with only one static variable, and this should be of your singleton class.
2) You can make clients to see "snaphots" (or copy of the real data). Some real-life databases (or storage solutions - because for me it's a clear separation line between the two) have this approach. However, this would complicate the things.
3) The correct instantiation code for an object that should be instantiated only once (doesn't matter if it's singleton or not) is:

public X getInstance(){
if (xinst == null) {
synchronized(syncObject) {
if(xinst == null) {xinst = new X();}
}
}
return xinst;
}
 
Czarak Ynehac
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Gigel,

Thank you for your reply. However from my previous post:


Also, the thurst of my post was a desire to move away from creating Data as a Singleton, so in the context of this thread I think this is a moot point.



I understand how to implement the Singleton Design Pattern, but this thread was about designing my SCJD without using a Singleton anywhere as I believe it is not an appropriate Design Pattern to use in my SCJD.

I have just been able to clarify something in my mind this afternoon. In my previous post I said:


The issue of clients instantiating Data with differet DB files is further confusing me. If we thought about all clients only using one DB file then one static collection in the Data class would suffice to track locked records across multiple instances of Data, but what about when there are multiple instances of data looking at multiple DBs?



Of course clients don't instantiate the Data class. Clients only connect to an already up and running server which will include the instantiated Data object(s). Also my instructions say it is safe to assume that only my server will be accessing the DB file so I don't have to worry about other servers accessing this file while my server is running. So no need to worry there (I hope!?).

So now I believe there is no problem having no control whatsoever on the instantiation of Data. Once the server is started, for every client which wants a connection to the server a new instance of Data will be created. Data will have a class (static) variable which is a collection of locked records. Lock and Unlock will add and remove records from this static collection and the Create, Update and Delete methods in Data will have blocks which synchronize on the static lockedRecords collections object before modifying the DB file. If anyone can comment on the possible validity or otherwise of this approach, your input would be much appreciated!

Thanks,

Czarak.
 
hatim osman
Ranch Hand
Posts: 105
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi there...
Czarak, I am implementing a socket based solution for the test, and I meant to do that so I can enhance my knowledge on Design Patterns. Although, it's tough but I am enjoying it. If you want to implement a Mediator Pattern, then your classes must be designed with this pattern in mind, I designed my classes so that they know little about each other and here where the Mediator Pattern comes into play. It controls how objects communicate with each other in a well defined way either by doing the job or delegating the request to the right class. And in some cases, it can be thought of as a centeral access point to any other class or functionality.
In my implementation, I have the Object App, some of its tasks are the following:

1. provides a single access point to suncertify.properties through:
App.setProperty(), App.getProperty()
my GUI configuration and others make use of these methods.

2. creates and holds the Data class reference, it extracts the necessary information from the properties file

3. starts and shotdown the server... so that my controllers "ex. shutdown Button" doesn't have to know how the server is doing this

4. provide access to the status bar
App.showStatus(String message) ...and more

This pattern helped me alot when it came to: where to create objects and how to delegate calls between them.

Hatim
 
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Czarak,

Reading your later posts, I think you have moved away from the idea of a Singleton - I think this is a good thing.

When you look at the methods of the Data class, you should realise that there is nothing at all in it that is specific to B&S - all the methods could be used on any table as long as it conforms to a particular table structure (which your magic cookie should confirm for you (excercise for those who are bored: find the correlation between the version of your assignment and the magic cookie)).

So at some point in the future, the company might decide to create another table (for example to store a table that relates customer numbers to their names and addresses). As long as they keep to the same file structure they should be able to use the same Data class to handle it.

However if your Data class is a Singleton, there is no way that they could have both tables in the same application. If your class is a Multiton or has no restrictions on number of instances (it is up to the class that uses the Data class to handle number of instances appropriately) then you can use the same Data class to handle multiple tables within the one program.

Note: This is not implying that you have to write your Data class such that it can handle multiple tables right now. But it is easier to change the Data class at a later date to handle multiple tables if it is not a Singleton.

Regards, Andrew
 
Czarak Ynehac
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Andrew,

Thank you for your helpful reply and thankfully now I have arrived at thinking about the project the same way as you suggest above and understand why.

Now that I have moved away from the idea of singelton or multiton for the Data class, one issue is still bothering me. In my Data Class, I have a Collection of lockedRecords and I have a RandomAccessFile.

I intend to declare the Collection of lockedRecords as Static, so that no matter how many instances of Data there are, they can all co-ordinate their locking on this Collection.

I am not so sure about the RandomAccessFile which is a handle for the physical db file. When I was thinking of making Data a Singleton I did not have to worry about this.

But now if I have multiple instances of Data I wonder should the RandomAccessFile be a class or instance member of the Data class?

I haven't been able to pin down information which makes this crystal clear to me yet.

My thoughts at the moment are:

1) If RandomAccessFile is made a class member of Data, does this reduce the concurrency of my application when there are multiple Data objects in existence?

2) If RandomAccessFile is made an instance memeber of Data, does this invalidate my locking mechanism?

At the moment I am leaning towards making the RandomAccessFile a member variable of data as I'm tentatively thinking that this will not invalidate my locking mechanism and it will aid the concurrency of the application.

Any comments very welcome!

Czarak
 
Andrew Monkhouse
author and jackaroo
Posts: 12200
280
Mac IntelliJ IDE Firefox Browser Oracle C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Czarak,

  • If RandomAccessFile is made a class member of Data, does this reduce the concurrency of my application when there are multiple Data objects in existence?
  • If RandomAccessFile is made an instance memeber of Data, does this invalidate my locking mechanism?


  • At the moment I am leaning towards making the RandomAccessFile a member variable of data as I'm tentatively thinking that this will not invalidate my locking mechanism and it will aid the concurrency of the application.

    No matter what you do, there is only one physical file on disk. Having multiple instances of the RandomAccessFile may or may not help concurrency - some operating systems allow multiple file pointers per file as long as they are working on different disk blocks or different pages, and some do not. Java makes no guarantees as to what will happen in this case.

    Note that I am not saying that this is a bad idea, I am just saying that you should not justify this in your choices based on improved concurrency.

    One other thing to be aware of - some operating systems limit the number of possible open file handles per application (usually any operating system that is designed for multi user / server applications). So you might have to develop a pool of file handles, or allow the number of open file handles to be configured, or develop an error handler to cater for this so that the end user still gets their desired results.

    As to whether it invalidates your locking - you should be able to write your locking code independant of this. That is the nice thing about working to an interface - you should be able to completely rewrite the code behind the Data class as the implementation details are entirely up to you - the users of the Data class neither know nor care about the implementation details.

    Regards, Andrew
     
    Czarak Ynehac
    Greenhorn
    Posts: 13
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi All,

    Thank you for your reply Andrew, your insight is always very valuable.

    So having multiple instances (per instance of the Data Class) of the RandomAccessFile may or may not help concurrency depending on the underlying operating System. Therefore I cannot make any claims about it helping the concurrency of my application. If I were to implement it I would have to consider the issue you mention about operating system limits on the number of open file handles per application. So that seems like pain for no gain to me

    So I think I will go forward in the direction of making my collection of locked records a class member of the Data class and then try to ensure my locking mechanism is watertight with this design, which I'm confident is possible with the lockedRecords collection as a class memeber.

    Thank you again!

    Czarak.
     
    reply
      Bookmark Topic Watch Topic
    • New Topic