my dog learned polymorphism*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Too Simple? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Too Simple?" Watch "Too Simple?" New topic
Author

Too Simple?

David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
I've been lurking around here for a while. I've been working on my assignment for about a month and things are going well. However, I'm feeling uneasy about my design. I've tried to keep things simple, but now I wonder if there is something I am missing (Basically, I made the design too simple). So, I'm asking for comments. Basically Here is what I have:
========= Main Interfaces ===========
DataInterface - lists the public methods of the Data class.
RemoteDataInterface - extends the Data Interface (above) and also remote.
CommandInterface - defines execute()
============ Data side (Data Server) ==============
Data class - implements the DataInterface
DataServer class - extends UnicastRemoteObject and implements RemoteDataInterface.
- This creates an RMI Server. It creates a new Data object. It has the same methods as the Data class.
============ Business Logic (Data Client) ========
FBNFlightServices
- has two constructors. 1) first constructor creates a local Database connect (by using new Data(databaseName). 2) second constructor takes the RMI URL and gets a reference via the Naming.lookup(host) method. (I could easily do this in one method). This also has all the public methods of the Data Class.

============= Client side (UI) ===========

FBNTableModel - extends AbstractTableModel
- This class helps The JTable.

FBNClient
- This client does most of it's calls to the FBNFlightServices class. If it wants to search, it calls FBNFlightServices. Other than that, it deals with displaying the data and allowing the user to interact with it.

Command Objects - These classes take care of the various commands. I'm using (or at least trying to use) the command pattern. I use a private innter class that extends various listeners. The constructors take an object that implements a CommandInterface which defines the execute() method. I can pass any type of command object to the constructor. Now, my actionPerformed method basically has command.execute(). The command object knows what to do.
BookFlightCommand -
SearchCriteriaCommand -

==============

So far, things are working well (I have not implemented lock/unlock yet though). I've tried to keep everything simple, but now I'm concerned that things might be a bit too simple.
Basically FBNFlightServices takes care of deciding whether an RMIObject or LocalObject is needed. The client doesn't know. It basically believes it is communicating with the FBNFlightServices class. I did this so, that if at some time, I wanted to add a different type of server (say SOAP or CORBA, etc) I could add that logic in the Services class and wouldn't have to change the client at all.
I feel like this design is flexible and simple...however, after reading some of the posts on here, I hope that I'm not missing anything (other than the lock/unlock implementation).
Thanks for your insights and comments!
Dave.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17258
    
    6

Your design sounds flexible, and good. The command pattern is a good pattern.
All design choices need to be defended in the design.txt and essay exam, and if you feel confident you can do that, that I say you have a good innovative way of solving this assignment.
I will be curious to see how you implement the lock and unlocking of records, such that a client can only unlock records that it has locked itself, and that other clients can't lock a record that another client currently has locked.
Let us know.
Thanks
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Bal Sharma
Ranch Hand

Joined: Sep 19, 2001
Posts: 273
DataInterface - lists the public methods of the Data class.
RemoteDataInterface - extends the Data Interface (above) and also remote. ...

I am kind of confuse. Am I missing anything?
Does your DataInterface extends Remote or not?
If it does then it is fine. Your RemoteDataInterface can extends DataInterface and get Remote object. ELSE your RemoteDataInterface can extend only one interface either DataInterface OR Remote. Rest of it looks great. By the way, if DataInterface extends Remote how are you planning get rid of RemoteException in Data class?
Good Luck -Bal
Enrico Mannarino
Ranch Hand

Joined: Dec 14, 2001
Posts: 133
Hi David,
Looks good! I don’t think that it can be too simple if it works. Good design is always “simple”, but it can take you a long time to get there - a lot of refactoring and code changes.
I’ve been working on my assignment since 3 weeks now and I’m gonna upload in a day or two, taking the exam next Monday. Your design looks a lot like mine, but I didn’t use the command pattern.
Myself I started with the lock/unlock mechanism, because I thought that was the tricky part.
This weekend I did all the documentation. I even wrote a small program that recursively printed out all the files under the scjd directory, to put in the README.txt.
So soon I’m gonna send my baby to SUN.
Enrico
Rajesh Matti
Ranch Hand

Joined: Jan 07, 2002
Posts: 121
David-
One observation on using the command pattern for the reason you have mentioned. The listeners are exactly how this pattern is implemented in Java. Instead of execute, it uses, for example, actionPerformed(). You may have inner classes implementing some of these interfaces and doing the job themselves rather than delegating further to Command.execute(). I think, using command pattern for the reason you have mentioned is not required as it will act like a proxy, instead of being a command itself.
This is just a thought, may be I am wrong.
-Rajesh
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Thanks for the messages! It does make me feel a bit better (at least I'm not way off base).
Mark, I too am anxious to see how I'm going to do lock/unlock. I started thinking about it this week, but then thought that I might need to revisit my overall design.
As I've looked through JavaRanch, I've really liked (and learned from) your posts! Thanks!
[ February 06, 2002: Message edited by: David Mullens ]
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Bal, Thanks for your comments!
You can have an interface extend two other interfaces. So, I have a DataInterface that extends nothing and a RemoteDataInterface that extends both DataInterface and Remote. You can't do that with classes, but you can with interfaces. ( 9.1.2 of JLS)
Since my DataInterface doesn't extend Remote (which it shouldn't because it shouldn't know anything about Remote), I don't have to worry about RemoteExceptions.
Dave.
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Good luck Enrico. I can't wait till I'm there too. I have most of the requirments implemented except for lock/unlock (I've been dragging my feet on this one). After that, I have a lot of code clean up and documentation, so it will be a while for me.
I'm really trying not to over analyze things and keep the design simple. I just hope that I haven't made some big oversight.... Thanks for the comments.
Dave.
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Rajesh,
I guess I don't understand what you are telling me (I have that problem at times). Basically, I still do an addActionListener, addMouseListener, etc, however, my actionPerfomed looks like:

I pass an object into my listener's constructor that implements my CommandInterface interface. The object knows what to do. This has really cleaned up my actionPerformed methods a lot. It also gives me the side benefit of sending the same command object to a different listener (say a one that extends MouseAdapter) and if the mouse button is clicked twice, the same command is performed.
I have trouble following some of the pattern books, so I might not have it quite right. If not, someone please let me know.
Thanks again for any insight.
Dave.
[ February 06, 2002: Message edited by: David Mullens ]
Enrico Mannarino
Ranch Hand

Joined: Dec 14, 2001
Posts: 133
Thank you David!
For lock/unlock you easily search this forum for ideas.
Enrico
Rajesh Matti
Ranch Hand

Joined: Jan 07, 2002
Posts: 121
Dave -
The listener you are registering with, say an actionlistener with a button, itself represents a command pattern. Instead of having 'n' commands, you may as well use action listeners as your command objects!!!.
For example: your code may look like this.
buttonOk.addActionListener(new MyActionListener(new okButtonCommand()));
buttonCancel.addActionListener(new MyActionListener(new cancelButtonCommand()));
but consider,
buttonOk.addActionListener(new ActionListener() {
public void actionPerformed() {
....
}
});
buttonCancel.addActionListener(new ActionListener() {
public void actionPerformed() {
....
}
});
The above code itself represents command pattern, meaning that, listeners in Java are designed after command pattern.
Hope that helps.
-Rajesh
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Thanks Rajesh.
There are a couple of reasons why I decided to do it the way I did. One reason was maintainablity. If I used anonymous inner classes, and needed to make changes in the logic, I would have to go through the code looking for all my different actionPerformed methods.
I also believe this helped me to reuse my logic. I have this in code:

Then later:

So, I'm able to re-use any logic I created. If I need to make changes to it, I can do it in once place rather than two (or more).
I also like separating the action logic from my UI. That way, at some point, one person could work on the UI while another one could work on the commands. The person working on the UI wouldn't care what the commands did, only where and to what they need to be added to.
Over all, I believe it made my code cleaner (and I hope) my design a bit easier to understand.
The downside is creating extra classes (for the commands) and making sure the command classes have all the references they need to do their job. Nevertheless, I like being able to edit the class that deals with the command to book a seat or searching, rather than having to look through my code to find them.
Peace,
Dave.
ravi janap
Ranch Hand

Joined: Nov 04, 2000
Posts: 389
Hi David
I am still in my design phase of my application.
I have been thinking about my design , studying sun's requirements and also studying other's design.
I have studied your design and mine is somewhat closer to yours.
My concern is why the FBNFlightServices or the DataServer class should have all the public methods of Data class implemented again in the respective classes ? Is it for purely meeting the sun's requirement specification ?
How does the code work ?
I am thinking of code like this.
Please correct me of I am wrong....
public class FBNFlightServices {
Data data;
public FBNFlightServices(String mode) {
if ( mode.equals("local") )
data = new Data(dbName);
this.data = data;
}
public int getRecordCount() {}
int count = data.getRecordCount();
return count;
}
public static void main(String[] args) {
FBNFlightServices services = new
FBNFlightServices("local");
services.getRecordCount();
}
}
and you have the same method defined in Data class
public class Data {
public int getRecordCount() {}
xxxxxxxxxxxxxxx
}
}
-- Ravindra


SCJP, SCJD, SCWCD, SCBCD, SCEA
Rajesh Matti
Ranch Hand

Joined: Jan 07, 2002
Posts: 121
David-
================================================
One reason was maintainablity. If I used anonymous inner classes, and needed to make hanges in the logic, I would have to go through the code looking for all my different actionPerformed methods.
=================================================
Well, I did not say it has to be anonymous inner class, it can be an outer class just like your TypeOneCommand().
==============================================
I also believe this helped me to reuse my logic.
==============================================
Surely, even otherwise you can do so by making a named classes implementing actionlistener interface, you can register the same object to a button, toolbar command button and a menuitem. This approach is very common.
I may be missing something here. Just wanted to clarify.
-Rajesh
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
janapareddy,

I don't have Sun's requirements in front of me. However, I do have all of Data's public method in my BusinessClass.
I had wanted to use a Facade or Adapter pattern. I'm going to have to go back to some pattern books to see which one I have (if either).
Your code looks pretty much like the way I was heading. I'm sure there are other ways to do it. One of my goals was to make things easy on the client end as far as local/network connection was concerned. The BusinessClass decides which type of object to return and just passes the calls on to it.

I also have the BusinessClass take care of the exceptions, so the Client doesn't really need to know about RemoteException (or whatever else I decide it doesn't need to know about).
Dave.
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Thanks Rajesh!
I need someone to push my design decisions! I had thought about creating "command classes" that implemented the various listeners. I decided against that. I wanted to be able to create an object that knew how to excute it's own command (so to speak) no how it was going to be used.
In my client class, I have two inner classes. One implements ActionLister, the other extends MouseAdapter. By leaving the command classes generic (by only implememnting a CommandInterface) I was able to pass in the same command object to both inner classes constructors. That way, in actionPerformed() I could do a command.execute() and also in mouseClicked() I could do a command.execute().
I can also pass any command class that implements the CommandInterface and it should work. So, I get rid of all the if statements and just do an .execute() and the object takes care of the rest.
I tried to follow the command pattern in the book "Applied Java Patterns". Not sure if I got it right, but it seems to work okay.
Dave.
Rajesh Matti
Ranch Hand

Joined: Jan 07, 2002
Posts: 121
David-
Sounds good.
Good luck,
-Rajsh
jefferson p
Greenhorn

Joined: Mar 06, 2002
Posts: 10
Hello Everyone,
I'm new here and trying my hand at the dev cert. I'm exploring several approaches using rmi. Some things I don't understand here that have been driving me crazy -
1. if RemoteDataInterface extends the DataInterface AND remote, does it override the methods in DataInterface?
2. Do the methods in RemoteDataInterface throw RemoteExceptions?
3. When the DataServer implements RemoteDataInterface do the implemented methods throw RemoteExceptions?
Uggh - 4 hours last night driving me nuts!
Thanks and hello!
Jeff
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Hi,
I'll try answering your questions...although others on here might be able to do a better job
1. if RemoteDataInterface extends the DataInterface AND remote, does it override the methods in DataInterface?
2. Do the methods in RemoteDataInterface throw RemoteExceptions?
3. When the DataServer implements RemoteDataInterface do the implemented methods throw RemoteExceptions?

1). I wouldn't say it 'overrides' them. I would say it implements them. The Interface is abstract, so there are only method signatures. Nothing to override.
2). There are no methods in remote interface. Just this:

3). Yes.
I know the answers are short....hope they help you out though....
Peace,

Dave.
jefferson p
Greenhorn

Joined: Mar 06, 2002
Posts: 10
Thanks David!
Finally, I got it - sure seems easy once the lightbulb goes on (or flickers, in my case)
Whew - on to the UI now...
Jeff
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi David
Will methods DataInterface throw RemoteException or java.lang.Exception.
I am asking so as RemoteDataInterface extends DataInterface and DataServer implemnts RemoteDataInterface.
I think it is required. what u say ?
Amit
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
I don't have the code in front of me, but I do believe DataInterface methods throw RemoteExceptions. I thought a long time about how to do this and decided to allow them to.
My Data.java file _does not_ throw remote, nor does it import any rmi classes. When you implement an interface, you can throw less exceptions than you do in your interface. That is what I did.
Not sure if it is solid design (although I like it better than throwing java.lang.Exception), but I ended up feel it was the best way to do it (for the design I used).
Dave.
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Hi, David
there's somthing i cant get clear in your design. Is RemoteDataInterface a sensible layer? Why not let the DataServer class directly implements DataInterface and extends UnicastRemoteObject? what's the use of RemoteDataInterface here? Is that for scalability?
David Mullens
Greenhorn

Joined: Jan 22, 2002
Posts: 23
Hi James,
RemoteDataInterface extends remote. DataInterface does not. I implemented DataInterface in the Data class (so I didn't want it to extend Remote).
Dave.
James Du
Ranch Hand

Joined: Mar 23, 2001
Posts: 186
Thanks David.
I thought maybe i lack the basic acknowledge of the methods for dealing with the RMI. Is remote interface(interface that extends Remote) a must for the 2 sides of RMI to communicate? I assumed that the client side only knows the DataInterface (which does not a extends Remote) and when it called lookup it get the RemoteServer which implements Remote interface and extends the DataInterface class as well.
In a word, my question is " Is it a must for the interface that bridges the 2 sides to be a subinterface of Remote?"
Thanks in advance
- James
jefferson p
Greenhorn

Joined: Mar 06, 2002
Posts: 10
After much thought, I've come to the conclusion that the confusion for me is due to how sublcasses declare exceptions. In normal inheritance, a subclass "extends" or provides "more" functionality than the parent class. In the case of exceptions, however, a subclass (or subinterface) can only throw "less" exceptions (only checked exceptions/sub-exceptions thrown by the parent class) than its parent class.
The RHE book says something to the effect of, "When it comes to exceptions, the design of a parent class must include exceptions that derived classes may throw, even though the parent class does not throw them."
So, why not just have one interface that extends remote, and throws database and remote exceptions?
Best,
Jeff
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Too Simple?