Hello All , I am finally in the RMI land! Based on the excellent tutorial that Andrew pointed to: http://developer.java.sun.com/developer/onlineTraining/rmi/RMI.html Fundamentals of RMI Short Course and the threads on the forum discussing this topic, I came up with the follow design. Actually I shouldn't say I did. I adapted Max's DVD design to my needs. After all, he told me to make it Bharat's DVDs! My GUIController class (as in MVC architecture) in the Presentation Layer calls the: RoomConnector (in the Network Layer) Class's static methods as follows: public static DBClient getRemote(String ip) throws RemoteException and public static DBClient getLocal() throws IOException As you can see, both return either remote or local versions of the DataAdapter object as DBClient Interface which is as follows:
Note: The local connection stuff works perfectly. Now I am about to test the RMI networking. Towards that, and the fact that I am using a "ConnectionFactory" pattern which guarantees a unique data object per connection since that is the fundamental premise that my locking strategy is based on, I have the following design: The getRemote method of the room connector class does the following: 1. It looks up the ConnectionFactory object (read interface) which is shown below:
2. It calls the create() method on the connection factory which returns an instance of the DataRemoteImpl class as a DBClient Interface. The connection factory code is shown below:
The DataRemoteImpl is the remote object which implements the DataRemote interface (extends both Remote and DBClient) and contains a reference to the DataAdapter class. It simply delegates the method calls, e.g., book, getRoomsUsingCriteria etc. to the wrapped instance of the DataAdapter class. My question is: is this a correct implementation of the Connection Factory Pattern? This seems almost trivial. Am I missing something? Regards. Bharat
Looks really good to me. The only difference between yours and my submission is that
RoomConnector (in the Network Layer) Class's static methods as follows
in my "RoomConnector" I ahd one method name and overloaded it. 1 method for remote one for local. So the client was always calling the same method name, but sent different parameters. For instance, in local mode, no parameter is sent. And in remote mode the server address and IP(if necessary) is sent, and because of the parameters the correct version of the method would be called. One question though. Is that my "RoomConnector" was instantiated on the clientside not the network layer, so I am a little confused at what you mean here. Mark
Hi Bharat, Just one question - you say your GUIController class connects to the connector. Or is it that the controller makes the connection which it passes to the model, and the model does all the work? Either option sounds counter intuitive to me. Consider if I wanted to add a set of screens for reporting functionality to your MVC:
As you can see, I only have one model, and it has all the connections to the database. Nothing else has a connection to the database (or is even aware that there is a database present). If it was the controller calling the methods in your factory, then I would have required two connections to the factory. One for the booking functionality, and one for the reporting functionality. Or even with the concept of the controller making the connection then passing it to the model - you still have two connections being made and passed to the model. What does the model do with this second connection? OK - the examples I gave are not very good. In reality you probably want to have a separate instance of the model for reporting and booking functionality. I am sure if I tried I could come up with two different booking views which you could toggle between (something for "normal" users and something for "power" users) in which case they would use the same model. Regards, Andrew
Your a bugger Monkhouse, think you've got your design sorted and you point something out. Very intresting though. I assume the model is a singelton that contains the various logic for accessing the db to provide booking, reading records etc, that provides a connection to the db server on start up. I can see how it's a very scalabe design. If I ever do this assignment again I will use that pattern. Tony [ September 13, 2003: Message edited by: Tony Collins ]
author and jackaroo
I assume the model is a singelton that contains the various logic for accessing the db to provide booking, reading records etc, that provides a connection to the db server on start up.
In the example diagram I gave, it would make sense to have a singleton. Likewise in the example I described where the user can toggle between a "normal" and "power-user" screen (in each case you would be displaying the same data) then you would probably look at having a single instance of the model. A singleton is not always required, although the descriptions of MVC often describe the model as though it were a singleton. One of the things that an MVC gives you is a clear delineation of responsibilities. The View is only concerned with displaying the data. The Controller is only concerned with translating actions from the view into actions for the model. The model is only concerned with providing access to the data model. As such, you should be able to swap the View and the Controller if ever you needed a different view. This is where code reuse really comes into play. Say you wanted to have a web version of your product. You would create a servlet as the controller, and a JSP page as the View. Still using exactly the same model. You have only needed to make a very minor change - everything else (the remote access, multi user database) still works. (I did this while studying for SCWCD - I decided to make a web version of FBNS. However after implemeting the web version with only two classes, I realised I needed a totally different project :roll: ) Regards, Andrew
Joined: Jul 30, 2003
Hello Andrew, I am afraid that I do not understand exactly what you are driving at here. I am a bit familiar with the MVC architecture as implemented in the STRUTS framework. I will try to echo back to you my design (Ok Max's design which I creatively stole and adapted to my requirements) in the following paragraphs and see if I can connect it to what you are saying. That should give you a basis to further clarify what you are getting at. If you look at the design shown in Max's book on page 209 that is basically what I have. I found that I could reuse it almost one hundred percent! That is why I closed-in (or at least seem to be closing-in until I find otherwise) on a working design so fast. This, along with the tutorial on RMI that you pointed out in another thread was just what I needed. Actually I didn't even have to finish the RMI tutorial. The second example, Simple Banking System, URL below was enough to give me a basic understanding of the "Factory Pattern" in RMI. http://developer.java.sun.com/developer/onlineTraining/rmi/exercises/SimpleBankingSystem/index.html Anyway, here we go: 1. As in Max's example, I have a public class called the "MainWindow". This is the view in my design The default construtor for this class creates an instance of the GUIController class. The constructor for the GUIController takes a single parameter which is a constant called GUIController.LOCAL_CONNECTION or GUIController.NETWORK_CONNECTION. 2. The GUIController class's matching constructor calls the setConnectionType method in the same class with and passes on the parameter received from the MainWindow class. The setConnectionType method calls either the getLocal() or getRemote(String ip) static methods of the RoomConnector class. My RoomConnector class is shown below:
Please disregard the e.printStackTrace() calls. I am going to go through the entire application and put in the proper exception handling and logging once I have a working application meeting the requirements. Also, I think it might be a good idea to pass a port number along with the ip address so that the RMI service can be bound to a user-defined port instead of the default 1099 port for the RMI. As you can see above, the getRemote method of the RoomConnector class returns an instance of DataAdapter class and assigns it to a DBClient client-side variable. Anyway, this return value is what gets stored in an instance variable of the GUIController class called "connection". The type for connection is "DBClient". 3. As I understand this with a bit of the EJB background in J2EE, this is my remote interface for the remote data object. Now I am free to call my "business" methods on it either locally or remotely. These business methods are "book" and "find" since that is the only functionality the client needs to implement. 4. Question is who and how are these business methods called, by the GUIController class or the RoomTableModel class which extends the AbstractTabelModel class? Right? Here we go..The only methods that are overriden in the RoomTableModel class are getColumnCount(), getValueAt(), setValueAt(), getColumnName(), and isCellEditable(). Additionally, there are two methods: 1. addRoomRecord(String  recordArray), and 2. setHeaderNames(String  headerArray). The addRoomRecord method is used to add a passed record object to a private ArrayList member called roomRecords. Similarly, the setHeaderNames sets the column header names. 5. Going back to step 1 above, when the MainWindow class instantiates a connection (DBClient) object either locally or remotely, it also creates an instance of the inner class called RoomMainWindow. This does the GUI layout work same as in Max's book. The MainWindow class also instantiates an instance variable called "tableData" which is of type RoomTableModel. This instance variable is the only connection that the MainWindow class has to the Model class. This is what is updated when a business method is called on the GUIController class that returns a new "view" object. Again, as in Max's book, there are two private inner classes called BookRoom and SearchRooms that are tied to the "book" and "search" JButton instances. Within the ActionPerformed methods of these methods, I call a method called setupTable(). This method is defined at the MainWindow class level, therefore, the inner classes have full access to it. This method is as follows:
As you can see above, the method basically 1. Gets the new view object using the Controller object, 2. Assigns it to the tableData (type is RoomTableModel) instance variable and 3. assigns this tableData object to the mainTable instance variable, where mainTable is an instance of JTable. With this as a background. Let me see if I understand what you are driving at:
Just one question - you say your GUIController class connects to the connector. Or is it that the controller makes the connection which it passes to the model, and the model does all the work?
As I see it, the GUIController does make the connection. However, the RoomTableModel class does very little work. There are only two methods that I have added 1. addRoomRecord(String recordArray) and 2. setHeaderNames(String headerArray). addRoomRecord method is called by the getRoomUsingCriteria(criteria) method of the GUIController class as follows:
I am not sure if I understand your response to Tony's post above. I think that I have given you enough "hooks" into my design. If you repeat what you are saying above with concrete references to my design, I will begin (hopefully) to see the light? Regards. Bharat
author and jackaroo
Hi Bharat, I think I may try and get Max involved in this discussion, because what he is describing in his book is not MVC as I know it. And he may disagree with everything I say below My comments have been based on whether this is MVC pattern or not. And I believe that this is not MVC. What you are doing is using the "View-Helper" design pattern. This is another good pattern, and quite applicable to the assignment. This post is just going to be discussing the differences between MVC and View-Helper. And why I believe that you are using the latter. Normally a class diagram for MVC would look like:
Note: although the database connection and the TableModel are not normally shown in an MVC, I have put them in there to help show how everything interconnects. The Model encapsulates the data and the rules used to access the data. It hides all the complexities of getting the data and how the data is stored. So the View does not need to know if the data is comming from one table in a database, 2 tables in a database or a flat file. The View does not need to know whether the data is local or on a remote machine. And so on. (The TableModel is not an MVC model. It does not abstract the access to the database in any way. It is just a way of describing the table.) The View displays the data provided by the Model. It sends actions to the Controller, and receives data from the Model. It may receive the data through the push or pull model (where the Model may push the data to all it's views, or the Views may have to pull the data from the Model). The View may do some (small) validation of the data, however it's focus is on displaying data to the client and allowing the client to enter data. It's focus is not on validation or checking access rights. The Controller translates actions from the View into calls to the correct methods in the Model. It can also do things like veryifying access rights. If you are using a Heirachial-Model-View-Controller the Controller would also be responsible for linking the Controllers together and for sending the action to the next link in the chain. Sometimes people decide that the link between the View and the model is undesirable, and they reduce the diagram to:
However what you (and Max's book) are describing is quite different:
In terms of patterns, the TableModel is irrelevant in that diagram - it is not required in order to meet a pattern (it is not the model in an MVC). If we take out the Database (I mentioned earlier, this would not normally be shown) then what we are left with is:
Then we see that this is a different pattern altogether - the "View-Helper" design pattern. This is quite a common modification to the MVC design, usually implemented when the controller has little or no functionality. One of the advantages the MVC gives you is the concept that you can abstract things like access rights into the controller. If you think about it in terms of areas of responsibility, the View is only responsible for displaying the data, the Model is only reponsible for abstracting the data. The Controller is responsible for control - it can verify whether a person only has rights to view available records, or whether they have rights to make bookings, or whether they have rights to add and delete records. (To give one example). The MVC is often used in web applications where the Model is often a bean, the View is often a JSP, and the controller is often a Servlet. Some links to design patterns:
Hello Andrew, Thanks for the response. My sole experience with MVC is in the Web world where STRUTS is the dominating standard. You wrote:
This is quite a common modification to the MVC design, usually implemented when the controller has little or no functionality.
I have to agree with you here. The controller servlet that we have for an industrial strength application that uses Struts 1.0, is a beast! It does all of what you mention:
The Controller is responsible for control - it can verify whether a person only has rights to view available records, or whether they have rights to make bookings, or whether they have rights to add and delete records. (To give one example).
Going through Max's book, I could see these departures from the Struts style MVC architecture were there, but all along, Max's book maintains a conceptual elegance and uniformity. Therefore, I paid little or no attention to what he chose to call what "works", and is quite similar to the MVC "mini" architecture. Like you, I am a fan of the design patterns. I have GoF patterns book which I found almost incomprehensible until I bought John Metskers excellent book explaining those patterns. See the link below: http://www.amazon.com/exec/obidos/ASIN/0201743973/ref=pd_ecc_rvi_f/002-7603199-2409635 Another book that I have used extensively since its very first edition is Core J2EE Design Patterns http://www.amazon.com/exec/obidos/ASIN/0131422464/qid=1063513389/sr=2-2/ref=sr_2_2/002-7603199-2409635 While I found all patterns discussed generally quite useful. In my humble openion, the differences in the patterns somtimes tend to be rather trivial. An example is that of Adapter v/s Mediator. To me, they both could have been one and the same. Mind you, they both are again, quite useful. I am not a patterns expert by a long shot. I do remain a patterns enthusiast, but I have quit worrying about what specifically a pattern am I using. Getting a clearer picture will be quite useful though when I start preparing for the SCEA exam. In your experience, how useful do you think is the ability to correctly classify a specific design pattern being used? In closing, I did go through your explanation carefully, and what you explain makes sense to me. Thanks for providing such an insightful discussion on this topic though. Regards. Bharat [ September 13, 2003: Message edited by: Bharat Ruparel ]
author and jackaroo
Hi Bharat, I also have the GOF book - I was lucky that I have used most of the patterns before picking up the GOF book, so 90% of it made sense to me. Another good book is Thinking in Patterns by Bruce Eckel (still a "work in progress").
In my humble openion, the differences in the patterns somtimes tend to be rather trivial.
Agreed. Likewise with the reasoning for using one over another.
I have quit worrying about what specifically a pattern am I using
To often I think people worry about how they can use a pattern in their design - or even worse, how they can use a specific pattern in their design. And they tend to force a pattern to be used where it does not fit. Patterns are very useful tools, but we should not be too concerned if we don't use a particular pattern or if we deviate from the standard usage of a pattern.
In your experience, how useful do you think is the ability to correctly classify a specific design pattern being used?
Hmmmm, there are two separate issues here. One is whether you can spot a pattern in the wild ("oooh, we should use a factory here") and the other is whether we should worry about misnaming a pattern. The first one is nice, but by no means essential. And trying to identify every pattern than could possibly get used can get in the way of a actually getting work done. The second one though can cause problems. If, for example, you said in your exam that you are using MVC, and the examiner decides that your assignment does not have an MVC, they may decide that the person who did the exam is different from the person who wrote the programs. Instant failure Likewise if you are in a design review at work, and you start by saying that you use pattern 'x' when you are not really using it, then it is worse than not talking about patterns at all: the audience will be thinking of your code in terms of the wrong pattern, and when they discover that it is not, they will have to go back over stuff that has already been covered in order to think about it in the right way. Regards, Andrew
Joined: Jul 30, 2003
Hello Andrew/Mark, My RMI Connection Factory design works like a charm! Thank you gentlemen for your help and support! Regards. Bharat
Hi Bharat, Unsurprisingly, as much as I love Andrew, I disagree with his interpretation of MVC. The classic example I use when I teach this stuff is a customer in a restaurant. If you consider the items on the menu to be the Model, the paper, print, font of the menu to the View, and the waiter ("no sir, you should really have the red wine with your steak") to be the Controller, you'll get a sense where things fall into place in MVC. Corresponding, the order the waiter delivers to the kitchen is the 'Model' as far as the kitchen is concerned. The Cook is the kitchen's Controller, and so on. Thus, you can have several MVCs sitting next to each other, and feeding each other in turn, So what does all of this have to do with my design? Well, the TableModel is the Model being created for the consumption of the GUI layer. Then the GUI does it's own MVC thing with it. Correspondingly, the DVDRecords are the Model being presented to the middle tier from the backbend tier. Thus, contrary to Andrew's interpretations, I see the TableModel as the model, which explains the Model piece in the diagram. In Andrew's interpretation, The Model is strictly what the back end manipulation as a logical abstraction between itself and the database. However, in my interpretation, the model is what the current layer manipulates in lieu of the complexity of the previous layer, not just the database. If you consider your application to be three 'mini' applications (namely, the GUI, the BusinessLogic, and the DBDriver), then you'll see how each layer produces a model, in turn, for the next layer. The DBDriver layer parses Files and produces (Models)Records, which it feeds to the BusinessLayer. The businessLayer parses Records and produces TableModels(Models) which it feed to the next layer, and the GUI consumes TablesModels(Again, just another model), and provide a visual(model) for the human client. However, all of this is just the naming of things: it doesn't really have anything to do with the concepts. If you have the concepts down, then you're ok. And it seems like you do, so we're ok . BTW- the reason this is somewhat different from Struts is because Struts actually uses a variation of MVC called Model2. The main difference being that Model2 architecture requires feedback from the User before it update itself, where traditional MVC allows this to driven by the MVC layer directly. In keeping with the restaurant example, Model2 is a fast food restaurant, where the system can't interact with you until you interact with it first (which makes a lot of sense, in the context of a web browser). The traditional MVC would be more of a traditional system, where the waiter might interact with you without your prompting( say, to take you plate away, or to see if you need more water). HTH, M [ September 15, 2003: Message edited by: Max Habibi ]
Hi Max, Thanks for explaining your understanding of MVC. It is good to be able to consider alternate understandings. Just to keep to the restaurant concept, I will put my understanding in the same format: In my way of thinking, the blackboard menu (for chef specials - in other words a changeable list) is the View, the waiter is the controller, and the chef is the model. I see something in the menu (view) I like, and I tell the waiter (I do something which triggers the controller). The waiter goes and tells the chef that I ordered some Oysters (triggers an action on the model). The chef starts abusing everybody for having Oysters on the menu in September (my brother is a chef ) so the waiter comes back and crosses the oysters off the menu (the view gets updated). I then make another choice which gets fulfilled. Regards, Andrew [ September 15, 2003: Message edited by: Andrew Monkhouse ]
town drunk ( and author)
Joined: Jun 27, 2002
Originally posted by Andrew Monkhouse: Hi Max, Thanks for explaining your understanding of MVC. It is good to be able to consider alternate understandings. Just to keep to the restaurant concept, I will put my understanding in the same format: In my way of thinking, the blackboard menu (for chef specials - in other words a changeable list) is the View, the waiter is the controller, and the chef is the model. I see something in the menu (view) I like, and I tell the waiter (I do something which triggers the controller). The waiter goes and tells the chef that I ordered some Oysters (triggers an action on the model). The chef starts abusing everybody for having Oysters on the menu in September (my brother is a chef ) so the waiter comes back and crosses the oysters off the menu (the view gets updated). I then make another choice which gets fulfilled. Regards, Andrew [ September 15, 2003: Message edited by: Andrew Monkhouse ]
I don't really think of it as an alternative interpretation: I think of it as a different perspective on the same thing. To wit, your post doesn't contradict anything that I explained above . The point to my design is that each layer, ultimately, produces a model for the next layer. The waiter produces a Model for the Kitchen (a customer order), the Kitchen produces a model for the grocer( the items on a grocery list), etc. That's the point of the design in my book. Three small layers, each with their own micro MVC world. I think that you're seeing the model from the mid tier, and assuming it's the model for the GUI tier. I must not have done a great job explaining it in the book. M