File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Swing / AWT / SWT and the fly likes Another MVC question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Another MVC question" Watch "Another MVC question" New topic
Author

Another MVC question

Geoff Berl
Greenhorn

Joined: Apr 13, 2011
Posts: 24

I think I am starting to get the idea of how to implement an MVC pattern, I just have a few questions on the specific details for my current project. Currently I'm working on a project that is a simple single frame (that will change later) quiz GUI to quiz a user on Karate terms. I have a Model, View and Controller and I also have QuizQuestion and KarateTerm Objects.

My model is gathering a list of KarateTerms from a text file and then I want it to generate a random question with random answers along with the correct answer. I'm getting a little confused as to how to break the processes up.

I guess my first roadblock is which logic goes where....
So my model creates a question and updates the view, then the user makes a selection, the controller sees it and sends that selected answer to the model. Would the model then check if the answer is correct or should that logic be in the Question Object?

Here is the entire code so far, if anyone feels ambitious enough to check it over can you tell me what your initial thoughts are on my structure?
I know my View is very simple and ugly but I only created it to test my model and I see there are flaws with it but I'm not sure how to proceed.






Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7492
    
  18

Geoff Berl wrote:I guess my first roadblock is which logic goes where....
So my model creates a question and updates the view, then the user makes a selection, the controller sees it and sends that selected answer to the model. Would the model then check if the answer is correct or should that logic be in the Question Object?

Well, first I must admit to a certain bias here, because I hate GUI programming; but it's always seemed to me that the 'V' part of MVC is the least important when it comes to design (and I fully expect to be flamed by all manner of 'V' geeks ).

The fact is that if you get the M and the C right, the V part (outside the actual display code itself) should simply be a bunch of messages passed between C and V, that cause V to display something new or return information/requests received from the user.
Simply put:
M = Information & Business rules
C = M→V Translator & Traffic warden
V = Display
and the hardest part of getting MVC right is to separate those three things as completely as possible.

If you get it right, you should be able to write your V component as a bunch of Scanner and System.out.println() statements to prove that the concept and application logic work before you even start work on your GUI. That part may involve refining the messages between C and V, but should almost never affect the M part.

You'll also find that the programming world is divided into M-C specialists (duffers like me) and V-C specialists (high-flyers that quickly tire of banging out GUI code and go create companies like Apple), with the best of the latter usually having a bit of nous about the M part as well.

Don't know how much that helps; but it's the MVC world according to me.

Winston


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
Geoff Berl
Greenhorn

Joined: Apr 13, 2011
Posts: 24

Winston Gutkowski wrote:If you get it right, you should be able to write your V component as a bunch of Scanner and System.out.println() statements to prove that the concept and application logic work before you even start work on your GUI. That part may involve refining the messages between C and V, but should almost never affect the M part.


Interesting, I hadn't even thought of using the command line as a "V". That would make it much less confusing to me since I find it slightly overwhelming trying to create all three at once. I'm going to do that.

Since my previous post, I have created completely new Quiz, Question and Choice objects and created a method that generates a quiz. I tested and it works great but now what would I do with the quiz, should I send the entire quiz to the view or just each question? I guess I just don't know how much I should send to the view at one time. If I send the Quiz, then the view would have to parse the quiz which I would guess is "logic" and therefore shouldn't be done in the view. So should I send the question? But if I send the question, the view will need to parse the choices and again, that seems like "logic". So how primitive should I go when sending data to the view?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7492
    
  18

Geoff Berl wrote:Interesting, I hadn't even thought of using the command line as a "V". That would make it much less confusing to me since I find it slightly overwhelming trying to create all three at once. I'm going to do that.

Just don't forget to still write it like a proper V component.
That is to say, it should still communicate with your C component via a set of designed methods.

Since my previous post, I have created completely new Quiz, Question and Choice objects and created a method that generates a quiz. I tested and it works great but now what would I do with the quiz, should I send the entire quiz to the view or just each question?

Well, a Quiz sounds to me like data, which would put it in the M portion, so it shouldn't be seen by the V at all. How you communicate it to the C component is another matter altogether. Question: Is it likely to change?

Remember: V communicates with C; M communicates with C. V should NOT communicate with M directly.

Winston
Geoff Berl
Greenhorn

Joined: Apr 13, 2011
Posts: 24

Winston Gutkowski wrote:Well, a Quiz sounds to me like data, which would put it in the M portion, so it shouldn't be seen by the V at all. How you communicate it to the C component is another matter altogether. Question: Is it likely to change?

Remember: V communicates with C; M communicates with C. V should NOT communicate with M directly.

Winston


Yes Quiz is data which is created and stored in the Model but any time that changes the model is sending it to the view(s). Should I not send objects to the view?

I wanted to build an MVC with the idea that it will change. I would like to add more quizzes and different views.

I have M communicating directly with V but definitely not the other way around.
Tyler Kenna
Greenhorn

Joined: Sep 08, 2012
Posts: 7
Hi,
I have been doing a lot of research on this subject as well, so perhaps I can add some insight on this subject. The idea is to have your model and your view completely separate. Neither should have to know about the other. I have seen perfectly acceptable programs where the view knew about the model, but Java provides a very nice set of classes to handle this problem much better: Observer and Observable.

Now, the model really shouldn't be communicating directly with the view. A model's sole purpose is to hold data, keep track of it. A view's sole purpose is to display data. If you link these two together, anytime you make changes in the code for one, you will probably have to adjust the code in the other. This does not go along well with OO's encapsulation. For example, let's say I have a model, which has information regarding sports statistics. I have created a view that displays certain aspects of this model, and written the code in the model to update the view directly. I have now programmed to an implementation rather than an interface. What happens when I need another view based on the same model, but that displays the information slightly different? I have to create the view, but then I also have to ADD code to the model to account for the new view. Now what if I need 20 more views based on the same model? 20 more sections of code must be added to model, and now our class has gotten out of hand. Hence the reason you need to keep model and view separate.

Best way to remedy this: Observer and Observable. Observable has two methods called setChanged() and notifyObservers(). If your model is now observable, it doesn't care what views are watching it. It just calls notifyObservers(). Now in your driver class or your controller, you can call model.addObserver(view) which will make your view class (which has implemented Observer) "listen" to the Observable model. When it hears model call notfiyObservers(), it then runs its own update() method (required by Observer) and carries out whatever code you have placed in it. That way, you can create both classes without either one having to know about the other.

An important detail about these methods: notifyObservers can pass any type of object you want, including "this", i.e. notifyObservers(String). Update has two arguments, Observable o, and Object arg. Object arg is the same object that you passed in the notifyObservers, if you so choose to pass one. This opens up more possibilities that allow your view and model to function without knowing the other one exists.

Hope that makes sense!

Aeiouy

Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7492
    
  18

Geoff Berl wrote:Should I not send objects to the view?

Not directly. Tyler has described it very well. The idea is to "decouple" the Model from the View by forcing it through an intermediary (the Control). This allows the View to deal with data in an abstract form (ie, probably some form of Java collection) without having to worry about where it's kept or how it's fetched or updated.

There's a very famous aphorism in IT:
David Wheeler wrote:Every problem in computer science can be solved by a layer of indirection.

and you'd be surprised how often it holds. A much simpler example of the same thing is providing "getter" and "setter" methods instead of giving clients direct access to your fields, but the principle is the same.

HIH

Winston
Geoff Berl
Greenhorn

Joined: Apr 13, 2011
Posts: 24

Tyler Kenna wrote:Best way to remedy this: Observer and Observable. Observable has two methods called setChanged() and notifyObservers(). If your model is now observable, it doesn't care what views are watching it. It just calls notifyObservers(). Now in your driver class or your controller, you can call model.addObserver(view) which will make your view class (which has implemented Observer) "listen" to the Observable model. When it hears model call notfiyObservers(), it then runs its own update() method (required by Observer) and carries out whatever code you have placed in it. That way, you can create both classes without either one having to know about the other.


Thanks for the info, but I think what you explained is exactly what I'm doing. In the main driver class I create a model and view and then I add that view to the model as an "Observer", if you look at my model class you will see that there is an addKarateTermView() method which allows me to add an interface allowing me to make multiple views which all share the same refresh() method. It's like using Observer and Observable but I haven't really dealt with those classes specifically so I made my own methods. The model has an updateModel() method which would be equivalent to the setChanged() and when updateModel() is called in the model it calls an updateViews() method which would be equivalent to notifyObservers().

I took this model from here but I have also seen it implemented in the Head First Design Patterns book in an example where a company has a weather meter spitting out data that it wants displayed, they go on to show you how to do this creating your own methods.. They discuss this pattern just before they introduce the Observer and Observable features stating that basically we didn't need to create those methods since java has the utility built in. Now, it does say in the book that their implementation is a bad one because their views are concrete and thus making the code too tightly coupled but I thought that's what using the interface would do to help. I just chose to do it this way to get a better understanding of how it works. This is a picture from a webpage which also depicts the specific MVC model I chose to use. There is a description of what the numbers mean but this shows you the idea.


Basically, my model doesn't know about the views it just has an array of observers which get updated with the model's data. And my view is not aware of the model, it just knows that it will be getting some data through an inherited refresh() method so that it can update its fields. When my view performs an action, the controller sees it and notifies the model if necessary and possibly updates all of the views.

But, all that being said, I will try to work on implementing the Observer and Observable features since they would decouple my objects even further eliminating the need for the model to be aware of the specific interface(s).

What I am still trying to figure out though, is what data am I supposed to send my views in the refresh method? In the first link I provided from roseindia.net they just have a very simple model and view where the view only shows four stings of data and the refresh method sends the four strings. The Head First book showed an example that used three strings. I'm dealing with a quiz that could have 100+ questions and a variable number of choices, should I have the method break down each question and just send something like refresh(String question, String[] choices)? This way the view wouldn't have access to the actual Quiz object. I'm guessing that is the key of the view, not only should it not be aware of the model but it shouldn't be passed any objects otherwise then the object could be manipulated by the view. Is this the right mindset?
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7492
    
  18

Geoff Berl wrote:I'm dealing with a quiz that could have 100+ questions and a variable number of choices, should I have the method break down each question and just send something like refresh(String question, String[] choices)? This way the view wouldn't have access to the actual Quiz object.

There's nothing wrong with sending a Quiz object to the View, particularly if it contains useful methods, providing it's an abstraction (ie, it doesn't contain any information/methods that deal directly with the data storage itself). In situations like that, it's quite common to have a Quiz interface, which has an implementation for use by the View component, and another (maybe with some data access methods) that is used by the Model side.

That way, all the View sees is a Quiz; it doesn't have to care about how its implemented. Layers of indirection again.

Winston
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Another MVC question
 
Similar Threads
Drag and Drop problem
need help with array
help needed in makin GUI (in netbeans) for a maths program(with lots of loops).
Nested Loop and getting parameter problem
Carry values between page submit