wood burning stoves 2.0*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Data singleton 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 "Data singleton" Watch "Data singleton" New topic
Author

Data singleton

Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
Is making Data class a singleton an error or acceptable if you explain why you do it in the design document.
Charles.


Charles.<br />(SCJD2)
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
It is acceptable if you can provide a sensible explanation why. I just have strong doubts whether you can provide a sensible explanation why or at least sensible enough to justify a crippling restriction on what used to be a nice reusable class. How many database-driven systems do you know that get by with exactly one table?
- Peter
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
The advantage I see is that you can use this singleton Data object to stay connected to the db.db file and serve as many clients as you want in a secure manner, depending on how you implements synchronization and locking. The relation between clients and Data is (n..1). You use your Data class as the one link between the server and the storage. Anyway somewhere you only have 1 data file db.db. You will need this (n..1)relation somewhere.
Charles.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Having a single Data instance sitting on top of one physical file is OK as long as you allow several Data instances to exist. The singleton pattern describes a scenario where there is only one instance of a class (if I remember correctly).
In other words, you're not talking about the singleton pattern. Maybe Factory Method / Abstract Factory was what you're really talking about?


Author of Test Driven (2007) and Effective Unit Testing (2013) [Blog] [HowToAskQuestionsOnJavaRanch]
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
I mean a singleton pattern, with a public synchronized static Data getInstance() method, and synchronized add(), delete(), modify() methods. It is quite thread safe, and work well with a LockManager class. I have done tests where 1000 threads read, modify, add a delete records at random, and have not lost a single byte of information.
Charles.
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
I see another advantage of the singleton Data. If you add or delete records, you can timestamp the single Data object and the next objects accessing it can check on the timestamp and be told that way that some important modifications happened to the data structure.
Lasse Koskela
author
Sheriff

Joined: Jan 23, 2002
Posts: 11962
    
    5
Originally posted by Charles Dupin:
I mean a singleton pattern, with a public synchronized static Data getInstance() method, and synchronized add(), delete(), modify() methods.


Ok. How do you support multiple database tables? Are you going to write a new class for each new table? I don't think so.
I believe preventing the existence of multiple tables (i.e. multiple Data instances) is not what the assessor will like to see.

Lasse
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Charles,
Are you suggesting a 'cache' object? That is, one this is, essentially, a stand-in for the single db.db file itself? Not that it's necessarily a bad idea, but I'm having a little trouble following you.
All best,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
[ February 18, 2003: Message edited by: Max Habibi ]

Java Regular Expressions
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
I agree with Peter and Lasse on the limitation of implementing Data as a singleton.
Try to think of a way to implement the n...1 relationship between clients and Data a different way.
One way would be to create a single object with a single reference to Data and then bind that object to the rmi registry. Then, it can hand out references to that one instance of Data to all the clients. Now you are in a position where the object bound to the registry can be modified to have multiple instances of Data if you have multiple tables, one Data for each table. It can then return references to those talbes to multiple clients, but ultimately there will be only one instance of Data for each table.
-BJ
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
BJ,
Are you suggesting that there is no intelligence in the server, that you put all booking mechanism in the client. I was personnally ready to add a book() method to the remote stub that the clients call and put all the booking mechanism (locking, read and modify calls to db) in the server.
The client can then call different servers with the same interface. The logic of each server can send different type of result to the clients.
To solve the Data singleton problem, create a DataInterface implemented by Data, and create a new FBNData class implementing it, singleton it, and connect it to the db.db file. Then Data is still available for reuse for other tables.
(I hope you follow me.)
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Charles Dupin:
Are you suggesting that there is no intelligence in the server, that you put all booking mechanism in the client. I was personnally ready to add a book() method to the remote stub that the clients call and put all the booking mechanism (locking, read and modify calls to db) in the server.
Bad move. Please read my response in this thread.
To solve the Data singleton problem, create a DataInterface [...] singleton it, and connect it to the db.db file. Then Data is still available for reuse for other tables.
You're using a hammer on a screw; yeah, you'll get it into the wall alright, but it's shaky and you're ruining your wall. All you really want to achieve is a 1:1 relationship between a Data instance, a LockManager, and possibly something like a ConnectionFactory. There are perfectly well-known ways to model this, and Singleton is certainly not it -- rather, you'd use instance variables and/or factory methods to enforce the correct relationships between your objects. You might find this thread useful.
Ah, Singleton. As our esteemed Eugene Kononov so poetically put it in his immortal contribution to the life and culture of this forum,
The Singleton, -- to use or not to use?
The grace of pattern overwhelms me, --
You've been the subject of abuse,
Or so the ranch sheriffs try to tell me
The heat of virtual hot spot machine
Make all my initializers lazy
But class loaders are really mean, --
They make two instances, amazing!
And then the garbage man comes in
To claim the memory unreferenced
And when I call it from the bean
It's doubleton, as if I had no preferance!
The call to get an instance comes along,
But quickly gets preemted by someone to blame.
I now have a tripleton, and I am prone
To crashes, errors, tears, and paine.

- Peter
[ February 18, 2003: Message edited by: Peter den Haan ]
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
Yes, I am suggesting that in my case there is no business knowledge on the server. The reason I did it this way was that one of Sun's requirements was to make the methods of Data available in the client. So I present my client with a remote object that implements IData. The client interacts with it through a facade class that has public high level business methods like bookFlight. It is a fat client.
Im not sure if I follow your last statement. I drew it out on paper to be sure, and it appears that we would end up with an interface DataInterface that has two implementing classes Data and FBNData. Did you mean for FBNData to contain a reference to an instance of Data?
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
BJ,
FBNData have no reference to an instance of Data. Just a sister class for the FBN db.db.
I am following you when you say that Sun's requirements was to make the methods of Data available in the client. But does it means that you put all the business in the client. I have all the Data methods available in the client, it could help Sun to test your locking system and thread safety with their own client application.
Charles.
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
Thanks Peter, I'll read all these threads.
I did not realized that Data was generic and supposed to be reused with other tables in the same server. It is very clear now.
If I am right, what Sun wants is not a Airline Reservation server, but an Airline Reservation application running against a Database server.
Charles.
(got some work to do !!!)
[ February 19, 2003: Message edited by: Charles Dupin ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Charles Dupin:
I did not realized that Data was generic and supposed to be reused with other tables in the same server. It is very clear now.
I am not sure how the instructions are worded these days. In my copy (3 years ago) the word "reuse" occurred a number of times.
But you don't need the instructions; just inspecting the Data class should tell you that it was conceived as a completely generic, reusable class. It follows that your additions to Data need to preserve that genericity. Whether the same applies to any subclasses that you write and the networked layer that you build on top of it is probably debatable, but the requirements gives you a strong hint that it ought to be generic as well. After all, you're asked to expose the server as a Data-like object. The Data interface is that of a generic database.
If you would write a FBN-specific network layer, then you would really want to turn into a business level layer, exposing bookFlight() and findFlights() methods and so forth.
So, even if the instructions no longer tell you to in so many words, I feel both existing code and requirements strongly push you towards a fully generic database layer.
- Peter
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
Peter,
There is not a word reuse in my assignement. The only idea of it is in this phrase: Your user interface should be designed with the expectation of future functionality enhancements, and it should establish a control scheme that will support this with minimal disruption to the users when this occurs.
About the server design I got: You must create a data server that will accept multiple concurrent network connections and allow them to interrogate and manipulate the database. Because multiple concurrent connections may exist, you must make both your server and the suncertify.db classes threadsafe. You may implement your threaded server in more than one class if you choose.
Thanks,
Charles
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
Originally posted by Charles Dupin:
BJ,
FBNData have no reference to an instance of Data. Just a sister class for the FBN db.db.
I am following you when you say that Sun's requirements was to make the methods of Data available in the client. But does it means that you put all the business in the client. I have all the Data methods available in the client, it could help Sun to test your locking system and thread safety with their own client application.
Charles.

No, nothing requires you to put the business logic in the client. You can do whatever you want as long as you can justify it. But if the Data methods need to be exposed on the client, why go through the trouble of fullfilling this requirement and then ignoring what you just made by making remote calls to high level business methods on the server. When I read this requirement I had a hunch that Sun was trying to steer me in a certain direction. Also, think about the wording:
You must create a data server
A big clue here is that they call it a data server, not an application server.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by BJ Grau:
When I read this requirement I had a hunch that Sun was trying to steer me in a certain direction.
Indeed. It's just a subtle nudge, as in: "You need to travel across the ocean. We're leaving you completely free as to the mode of transport you choose to use, but the vehicle you build must have a sail."
Well, you can try submitting a plane with a sail, I guess
Charles, please remember that the design you come up with will have to make sense in itself. If something is in there solely to satisfy the requirements, not because in your design it makes sense for it to be there, there's something wrong and you should arguably either junk the class (and clearly document why) or adjust the design.
- Peter
[ February 19, 2003: Message edited by: Peter den Haan ]
BJ Grau
Ranch Hand

Joined: Jul 10, 2001
Posts: 234
Originally posted by Peter den Haan:
Indeed. It's just a subtle nudge, as in: "You need to travel across the ocean. We're leaving you completely free as to the mode of transport you choose to use, but the vehicle you build must have a sail."
Well, you can try submitting a plane with a sail, I guess
[ February 19, 2003: Message edited by: Peter den Haan ]

Well said.
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
Ok guys,
You are perfectly right, thanks for opening my eyes. I'll redesign my work.
Charles.

Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
OK, I moved the business class to the client side.
In the server I only have left the DataInterface, a Controller class, the Data Class generically modified, the original Data.. classes, and a LockManager.
This LockManager can either be:
- singleton (sorry Eugene, I dont mean to be rude)
- created by each connection and working on a single static Map (you have got to have a single reference table somwhere, isn't it?)
- static
- ..
Are there a known patterns for lock managers?
I can already hear a whistle...
Charles.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
You don't need no stinkin' static singleton c... I mean class. Class. Yes, I definitely meant to say "class"
Ok. In my submission, I had a ConnectionFactory which was bound in the RMI registry (it had a different name actually, but that's not important). The client would call connect() on this factory to get a Connection which implemented DataInterface.
As this ConnectionFactory is responsible for creating all Connections, it is the ideal repository for things that needs to be shared between them. In my case, there were two such things, both stored in final ConnectionFactory instance variables: a Data instance, and a LockManager. My Connection was an inner class of ConnectionFactory and would be able to access these two directly; if you don't like inner classes, you can add getter methods and pass a reference to the ConnectionFactory into the Connection constructor, or alternatively just pass in the LockManager and Data directly.
This structure enforces the right relationships and cardinalities between ConnectionFactory, Connection, LockManager and Data. At the same time it only enforces those constraints that are dictated by the nature of the problem, and does not introduce arbitrary further constraints such as only being able to have a single database table.
In a good OO design, you would expect the class relationships and data structures to embody precisely the fundamental constraints of your problem. This helps make the design expressive, robust and flexible.
- Peter
[ February 20, 2003: Message edited by: Peter den Haan ]
Charles Dupin
Ranch Hand

Joined: Oct 18, 2002
Posts: 94
Great, Great, Great.
Thanks.
Charles.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Data singleton
 
Similar Threads
2 different types of singleton
Singleton Pattern
Single pattern
Concurrent invocation of a singletone method
NX: About read and write lock mechnism