*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes DataClient Adapter pattern Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "DataClient Adapter pattern" Watch "DataClient Adapter pattern" New topic
Author

DataClient Adapter pattern

Adrian Yan
Ranch Hand

Joined: Oct 02, 2000
Posts: 688
I use adapter pattern for my server-side implementation, but I'm still having problem with my client-side. The big problem is that since my DataClient supports both local and RMI mode, because of this, all my methods on DataClient throws RemoteException. I tried to use adapter pattern as suggested, but I just can't figure it out how to apply it, so my methods don't have to throw RemoteException in local mode.
Any help is appreciated!!!
Matt DeLacey
Ranch Hand

Joined: Oct 12, 2000
Posts: 318
Hello,
If you use a DataClient inteface that defines all the public
methods, then have LocalDataClient and RemoteDataClient implement that interface, then your LocalDataClient doesn't have to throw RemoteException. I may be wrong here, but it seems like I read somewhere that you have tried this approach, but perhaps you had the interface throwing remoteexceptions. I THINK the key is to have the interface throwing Exception. That way the localdataclient can throw whatever exceptions it likes and the remotedata client can throw whatever exceptions it like (in particular remoteexception). I think maybe you might have had a problem if you tried to have the interface throw a remoteexception. If I'm not mistaken an implementing class must throw no exceptions, the same exceptions of children of the exceptions thrown in the interface. Therefore, if you defined your interface to throw RemoteException, you'd have to throw it in both classes that implement that interface whereas if you define it to throw Exception, you're golden. That's the way I did it anyway. Hope that helps.
With Respect,
Matt
Adrian Yan
Ranch Hand

Joined: Oct 02, 2000
Posts: 688
Thanx Matt.
I'll give it a shot.
Rahul Rathore
Ranch Hand

Joined: Sep 30, 2000
Posts: 324
I have defined interface Database, which has all methods of Data class. The Database interface has methods throwing Exception. I have modified the definition of the Data class to make it implement the Database interface. The Database interface is extended by a RemoteData interface, which in turn is implemented by the RemoteData class, which is an adapter.
I have made the DataClient also implement the same Database interface - because as per specs we have to provide all methods of data class on the client-side also.
David Jon
Greenhorn

Joined: Feb 16, 2001
Posts: 17
Matt,
I don't understand how your solution would really work. If you have a class that instantiates objects of the type of your interface(which has methods which throw Exception) how do you catch the correct exception with out casting the object to the appropriate remote or local implementation??
Thanks,
David.
Rahul Rathore
Ranch Hand

Joined: Sep 30, 2000
Posts: 324
David
There is no need for casting. You are free to define multiple catch blocks- to catch any subclass of Exception or to catch Exception.
David Jon
Greenhorn

Joined: Feb 16, 2001
Posts: 17
Rahul,
yes, I understand this, but how would your calling application handle the fact that it would have to catch Exception. I don't think that this would be a particulary good idea due to the various runtime exceptions that subclass Exception.
I am aware of the fact that you could catch DatabaseException, then RemoteException but ultimately because of the way the interface is defined you have to catch Exception as well(unless you cst the implementing object) and re-throw it just in case it is something more serious(like a NullPointerException).
Jon.
Swapan Golla
Ranch Hand

Joined: May 31, 2000
Posts: 32
Dont you think writing two clients which almost have identical code a good idea in terms of design issues? I got rid of this problem by having a base DataInterface throwing Exception and then Data class implementing a LocalDataInterface(which extends DataInterface) and the remote class implementing a RemoteDataInterface(aslo extending DataInterface) . So, when you write the code for the client, you can write multiple catch blocks and cast the incoming object (Either remote or local ) to base DataInterface. Any comments?
With Regards,
Swapan.
Adrian Yan
Ranch Hand

Joined: Oct 02, 2000
Posts: 688
Matt and Swapan:
I wrote two seperate classes on client-side with almost exact code, the only difference is exception thrown. I don't see how this can be a good design, two classes performing literally the same thing.
Rahul:
Your idea of just throwing Exception on the interface, then each subclass throw specific exception is ok. But the question goes back the DataClient throwing unneccessary exception in one of the mode.
I assume your DataClient will do somethign like this:
private GenericData db;
public DataClient(xxxx){//assume local access}
public DataClient(xxxx) {//assume remote access}
public void book(some parameter){
try{
db.book(some parameter);
}catch(RemoteException e){
}catch(DatabaseException e){
}catch(Exception e){
}
}}
Once again, you are adding unuse exception in the code if the application is in local mode (RemoteException), and vice versa.
vladimir levin
Ranch Hand

Joined: Dec 19, 2000
Posts: 45
I have read that defining an interface to throw a generic
"Exception" is bad design. I haven't really got to the server
side of development on this assignment yet... Would you guys
consider this to be one of those "necessary evil" scenarios
or might there be a more elegant way to go?
Vlad
David Jon
Greenhorn

Joined: Feb 16, 2001
Posts: 17
Adrian - yes, this is what I am getting at. But what do you do about the Exception case. do you just re-throw it?
Vlad - I to believe that catching and throwing Exception is a bad design and should be avoided but I really can't see a way out of it .
David.
Matt DeLacey
Ranch Hand

Joined: Oct 12, 2000
Posts: 318
Adrian--I think we must be talking about different things as the two classes that implement my interface are very different. One is my localdataclient and one is my remotedataclient. One uses rmi and one communicates locally. Anyway, it's a system that suits my needs. Definately, points have been brought up about it's shortcomings, but I've not heard a way to do this that I like better. I'll keep this method until I do. I will switch if I hear something better. Incidentally, I have read of two people who used this way and received their certification. Doesn't mean it's the best way to go (clearly, based on what has beenw ritten here), but it CAN be a successful way.
With Respect,
Matt
Adrian Yan
Ranch Hand

Joined: Oct 02, 2000
Posts: 688
Matt, I'm not saying what you doing is wrong, because I don't know the right answer. I think I understand what you are saying. I don't know your code, but from the design, your lcoaldata and remotedata classes are probably similar in almost everything, except the constructors, right?
David, I basically handling everything in my two classes, similar to Matt's design. However, I'm trying to figure out how to avoid the mutiple Exception catching problem because every methods have to throw at least Exception, but shouldn't.
Rahul Rathore
Ranch Hand

Joined: Sep 30, 2000
Posts: 324
Adrian
I don't do db.book because I don't define any book() method on the server-side. That method is on the client-side.
But otherwise you are right- My DataClient implements the Database interface (which throws Exception) and it has a private data member which also implements the same Database interface. The data member has reference to the Data object (local access), or to the stub-object (remote access). The Data/stub object also implement the same Database interface. The DataClient simply implements the methods of the Database interface, by forwarding the invocation to the 'data' member which is having reference to the local data or stub object.
Yes I don't feel happy about forcing the DataClient to handle Exception, but the alternatives appeared to unnecessarily complicate the design.
Actually, though I did mention about having different catch blocks, my design is simpler (maybe not so good). I merely rethrow Exception. The exception is caught and handled by middle-layer application objects, which then convert it into a message which can be displayed by the user-interface. In my design an exception is simply a failure of an operation.
Maybe I am thinking too simplistically. Actually an exception may not necessarily mean that an operation has failed. Maybe permanent changes have been made on the database side. Properly I think the throwing of an exception should automatically cause a 'rollback' but I don't think such precision is within the scope of the assignment.
Swapan Golla
Ranch Hand

Joined: May 31, 2000
Posts: 32
I kind of agree with Rahul's thinking. Is it worth to have two classes to do almost the same thing or is it worth to have an additional exception being caught or thrown and thereby reducing a addtional logical class? I agree you have to create an additional interface and things like that.Its your choice to make and it should suit your overall application needs. I almost thought of using reflection API for this but it has some shortcomings of its own.
With Regards,
Swapan.
Adrian Yan
Ranch Hand

Joined: Oct 02, 2000
Posts: 688
I think we all use similar design to this problem. My concern is that since if I just rethrow Exception, The application (client) does not know which exception it is (Remote or Detabase), then I can't send more specific warning to the GUI client and the user.
I suppose this is OK because the scope of the project.
Thank You For the Info, GUYS!!!
Dilip kumar
Ranch Hand

Joined: Oct 16, 2000
Posts: 360
Hi,
Now I'm at this same crossroads. Is it worth to have two classes to do almost the same thing or is it worth to have an additional exception being caught or thrown ?
Any new ideas/ suggestions ?
Thanks
Dilip
Tom Peillon
Greenhorn

Joined: Mar 30, 2001
Posts: 9
A solution to this is to have your adaptor catch RemoteExceptions and throw DatabaseExceptions eg
catch (RemoteException e) {throw new DatabaseException("Connection to remote database lost :" + e.getText)
}
Terry McKee
Ranch Hand

Joined: Sep 29, 2000
Posts: 173
I was thinking of creating a general DataController interface that has all of the public methods of Data. All of the methods have a throws IOException. Some have an additional throws DatabaseException too. My thought is that you don't have to be so general as to use the Exception that is thrown but rather the IOException (which is a superclass of RemoteException). What does everyone think?
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: DataClient Adapter pattern