Design Question for Model and View

J

Jason Cavett

I have a question about a design for a model/view and communication
between the two.

I have a model (MainModel) that holds a Collection of project
objects. It keeps track of which projects are open, what the current
project is, it initializes projects and saves projects. I have a view
to this model which provides me access to these various tasks. (The
MainModel can have multiple projects open at a time. These projects
are shown in the view.) The view is an Observer of the MainModel.
This all works great.

The problem I run into (sort of a problem - I can easily hack around
it, but I'm wondering if there's a better way) is that it can be tough
getting information from the user when I need to accomplish a goal.
For example, if I'm closing an open project, the user selects "close"
in the MainView. Here is how I think it should happen - if there's a
better way, please let me know.

1. The user selects "Close Project"
2. The view (which knows about the model) calls "model.close()"
3. The model checks to see if the project is saved. If it's not
saved, the model notifies that view that it needs to ask the user if
they want to save before they close.
4. [TRICKY PART] - The view pops up a JOptionPane and asks the user if
they want to save. The user selects "Yes" The view sets a flag in
the main model notifying that it should save.
5. The model continues, sees the flag has been set to "true" and
saves, then proceeds to close the project.

Is this a good way to go about it? It just seems to me that there
could be a lot of flags floating about if I start doing more within
the MainModel.


Thanks
 
K

Kai Schwebke

Jason said:
For example, if I'm closing an open project, the user selects "close"
in the MainView. Here is how I think it should happen - if there's a
better way, please let me know.

here's my suggestion:

1. The user selects "Close Project"

2. The view (which knows about the model)
checks the isSaved-property of the model.
If the model is not saved, the view asks the user if
they want to save before they close.
If the users selects "Yes" the view calls the
models save method.

3. The view calls "model.close()",
Is this a good way to go about it? It just seems to me that there
could be a lot of flags floating about if I start doing more within
the MainModel.

By shifting the control to the view the flags and callbacks
can be avoided in this case.



Kai
 
S

Stefan Ram

Jason Cavett said:
The problem I run into (sort of a problem - I can easily hack around
it, but I'm wondering if there's a better way) is that it can be tough
getting information from the user when I need to accomplish a goal.

For example, a model operation might need a yes/no-information.

According to MVC, the model then would change a variable
»information_required« to be »true«. The View would be
subscribed to this as an observer and, thus, become notified
of the need. The view will create a yes/no-requester visible
to the user.

When the user decides to supply the information, the
controller will tell the model, which then will set
»information_required« to »false«, which will make the view to
close the requester.
the model notifies that view

The model must not know that there is a view, otherwise it
would be coupled to the view in a way that is not intended in
MVC.

It only knows that there are observers, so it ... (see above)
The view sets a flag in the main model notifying that it should
save.

In MVC, this would be the part of the »controller«.

But then, maybe you did not want to use MVC at all.
Is this a good way to go about it?

I can not determine, whether a strict and pure application
of MVC is advantageous in your case. I just wrote /how/ to
do it /if/ one wanted to do this.

Things might be simplified by a kind of »hierarchical MVC«,
where the confirmation-logic is contained entirely in the View
of the outer MVC, while it consists of an internal MVC
structure itself.
 
E

Eric Sosman

Jason Cavett wrote On 05/30/07 15:40,:
I have a question about a design for a model/view and communication
between the two.

I have a model (MainModel) that holds a Collection of project
objects. It keeps track of which projects are open, what the current
project is, it initializes projects and saves projects. I have a view
to this model which provides me access to these various tasks. (The
MainModel can have multiple projects open at a time. These projects
are shown in the view.) The view is an Observer of the MainModel.
This all works great.

The problem I run into (sort of a problem - I can easily hack around
it, but I'm wondering if there's a better way) is that it can be tough
getting information from the user when I need to accomplish a goal.
For example, if I'm closing an open project, the user selects "close"
in the MainView. Here is how I think it should happen - if there's a
better way, please let me know.

1. The user selects "Close Project"
2. The view (which knows about the model) calls "model.close()"
3. The model checks to see if the project is saved. If it's not
saved, the model notifies that view that it needs to ask the user if
they want to save before they close.
4. [TRICKY PART] - The view pops up a JOptionPane and asks the user if
they want to save. The user selects "Yes" The view sets a flag in
the main model notifying that it should save.
5. The model continues, sees the flag has been set to "true" and
saves, then proceeds to close the project.

Is this a good way to go about it? It just seems to me that there
could be a lot of flags floating about if I start doing more within
the MainModel.

There are a lot of ways to approach this. Since your
model apparently knows that it has been changed since last
being saved, it could publish that knowledge. The view
could call model.hasUnsavedChanges() to decide whether it
should get the user's permission before calling model.close().

A variant of the above is for the model to maintain a
counter that increments each time a change is made, and to
publish that counter via model.getVersion(). This lets a
single model be seen by multiple views, each (perhaps) with
its own backing store and its own notion of when things
were last current.

Yet another scheme is to use model.closeIfUnchanged()
and model.closeUnconditionally(). (model.close(boolean)
seems less mnemonic.)
 
L

Lew

Kai said:
By shifting the control to the view[,] the flags and callbacks
can be avoided in this case.

This is a very good principle to enforce between two components - distinguish
the initiator ("client") from the responder ("server"), in your case the view
and the model, respectively.

The responder should not initiate, thus the initiator need never respond.

The initiator asks the responder if it's "saved". Based on the answer, the
initiator might solicit information from the user. Based on that answer, the
initiator might ask the responder to save the data. After all that, the
initiator asks the responder to close (something).

This pattern avoids a lot of deadlock and complexity, and has surprisingly
wide applicability.
 
J

Jason Cavett

Kai said:
By shifting the control to the view[,] the flags and callbacks
can be avoided in this case.

This is a very good principle to enforce between two components - distinguish
the initiator ("client") from the responder ("server"), in your case the view
and the model, respectively.

The responder should not initiate, thus the initiator need never respond.

The initiator asks the responder if it's "saved". Based on the answer, the
initiator might solicit information from the user. Based on that answer, the
initiator might ask the responder to save the data. After all that, the
initiator asks the responder to close (something).

This pattern avoids a lot of deadlock and complexity, and has surprisingly
wide applicability.

Okay - this is primarily what I was wondering. The client/server (or
initiator/responder) model seems a lot less complex as opposed to pure
MVC.

Thanks
 
J

Jason Cavett

For example, a model operation might need a yes/no-information.

According to MVC, the model then would change a variable
»information_required« to be »true«. The View would be
subscribed to this as an observer and, thus, become notified
of the need. The view will create a yes/no-requester visible
to the user.

When the user decides to supply the information, the
controller will tell the model, which then will set
»information_required« to »false«, which will make the view to
close the requester.


The model must not know that there is a view, otherwise it
would be coupled to the view in a way that is not intended in
MVC.

It only knows that there are observers, so it ... (see above)


In MVC, this would be the part of the »controller«.

But then, maybe you did not want to use MVC at all.


I can not determine, whether a strict and pure application
of MVC is advantageous in your case. I just wrote /how/ to
do it /if/ one wanted to do this.

Things might be simplified by a kind of »hierarchical MVC«,
where the confirmation-logic is contained entirely in the View
of the outer MVC, while it consists of an internal MVC
structure itself.
From a theoretical standpoint, this seems to be the best way to do
this. At the same time, it seems overly complicated. I could easily
implement something like this as the foundation for MVC is already
there. I'm just wondernig if this would be the best idea.

Also - the controller - that doesn't necessarily have to be a separate
class, does it? (I didn't think so, but I always get a bit confused
on the actual layout of the model, view and controller. It seems
other people do as well.)

Thanks
 
L

Lew

Jason said:
The client/server (or
initiator/responder) model seems a lot less complex as opposed to pure
MVC.

The statement makes no sense. There is no correlation or conflict - one would
implement MVC using components that follow an initiator-responder pattern. Or
not. One could also implement a non-MVC solution using an initiator-responder
pattern. Or not.

And what do you mean by "pure" MVC? How does it relate to this discussion?

I would recommend the architectural model of MVC, or one of its close
relatives. It makes for a maintainable, stable product.

What complexity do you fear? Is avoiding it worth compromising the
maintainability and stability of the product?
 
J

Jason Cavett

The statement makes no sense. There is no correlation or conflict - one would
implement MVC using components that follow an initiator-responder pattern. Or
not. One could also implement a non-MVC solution using an initiator-responder
pattern. Or not.

And what do you mean by "pure" MVC? How does it relate to this discussion?

I would recommend the architectural model of MVC, or one of its close
relatives. It makes for a maintainable, stable product.

What complexity do you fear? Is avoiding it worth compromising the
maintainability and stability of the product?

See Stefan's post. The strikes me more as a pure MVC solution due to
the fact that the model is doing everything and the view is *only*
being a view for the model. (AKA - The view will have no logic
whatsoever.)

For example, in "non-pure" MVC...

The view asks the user, "This project is not saved. Do you want to
save?"
The user selects an answer.
The view checks the answer and based on the answer tells the model
what to do.

In "pure" MVC.

The view asks the user, "This project is not saved. Do you want to
save?"
The user selects and answer.
The view sends the answer to the model.
The model checks the answer and, based on the answer, performs the
action.


I'm guessing a separate controller may be applicable here, but I don't
see a *huge* need for a separate controller. As I stated in my post
below - I'm always confused how the controller fits into everything.
I've researched a bit online, but other people seem to have different
thoughts on how it fits in as well.
 
L

Lew

Jason said:
The strikes me more as a pure MVC solution due to
the fact that the model is doing everything and the view is *only*
being a view for the model. (AKA - The view will have no logic
whatsoever.)

For example, in "non-pure" MVC...

The view asks the user, "This project is not saved. Do you want to
save?"

No - that is not MVC. How would the view know the project is not saved? It
has to ask the model if the project is saved.
The user selects an answer.
The view checks the answer and based on the answer tells the model
what to do.

In "pure" MVC.

The view asks the user, "This project is not saved. Do you want to
save?"

No - that is not MVC. How would the view know the project is not saved? It
has to ask the model if the project is saved.
The user selects and answer.
The view sends the answer to the model.
The model checks the answer and, based on the answer, performs the
action.

What you call "pure" MVC is less conformant to the MVC pattern. In what you
call "pure" the model interprets the answer, but the answer is a view
artifact. Having the view interpret the answer and direct the model is more
"pure".
I'm guessing a separate controller may be applicable here, but I don't
see a *huge* need for a separate controller. As I stated in my post
below - I'm always confused how the controller fits into everything.
I've researched a bit online, but other people seem to have different
thoughts on how it fits in as well.

The controller receives the request directly, parses it enough to determine
which logic applies, sends the request data (possibly parsed first) to the
appropriate model logic. Based on a result condition from the model, it
selects the next view.

Another term for the controller is the "dispatcher". Think of a taxi service
- the dispatcher doesn't drive the cars, they select the next, nearest
available service component (taxi) to handle the request. To have the view
(telephone) interact directly with individual taxis would be horridly
inefficient - you could have dozens of calls go to one taxi and none to any of
the others.

The dispatcher needs some knowledge of the model (available vehicles) to
determine that you are asking for a limousine that seats eight, not a Mini
that seats barely two.

If you send directly to a "logic" component you lose flexibility in the face
of view evolution. (Taxi service via internet - now every cab needs a 'net
connection, unless you have a dispatcher.)

There is no "pure" version of any of these implementations. There will always
be boundary layers between model and controller and between view and
controller. The controller will do some things that arguably belong in the
view, and it will do some things that arguably belong in the model. It's part
of what makes programming more an art than a science.
 
J

Jason Cavett

No - that is not MVC. How would the view know the project is not saved? It
has to ask the model if the project is saved.




No - that is not MVC. How would the view know the project is not saved? It
has to ask the model if the project is saved.


What you call "pure" MVC is less conformant to the MVC pattern. In what you
call "pure" the model interprets the answer, but the answer is a view
artifact. Having the view interpret the answer and direct the model is more
"pure".


The controller receives the request directly, parses it enough to determine
which logic applies, sends the request data (possibly parsed first) to the
appropriate model logic. Based on a result condition from the model, it
selects the next view.

Another term for the controller is the "dispatcher". Think of a taxi service
- the dispatcher doesn't drive the cars, they select the next, nearest
available service component (taxi) to handle the request. To have the view
(telephone) interact directly with individual taxis would be horridly
inefficient - you could have dozens of calls go to one taxi and none to any of
the others.

The dispatcher needs some knowledge of the model (available vehicles) to
determine that you are asking for a limousine that seats eight, not a Mini
that seats barely two.

If you send directly to a "logic" component you lose flexibility in the face
of view evolution. (Taxi service via internet - now every cab needs a 'net
connection, unless you have a dispatcher.)

There is no "pure" version of any of these implementations. There will always
be boundary layers between model and controller and between view and
controller. The controller will do some things that arguably belong in the
view, and it will do some things that arguably belong in the model. It's part
of what makes programming more an art than a science.

Thank you for your explanations. It cleared up a lot.

One last question - a controller doesn't necessarily have to be a
separate class, does it? Can it be part of (from a class perspective
- not a logical one) the model or view - especially if it doesn't do a
whole lot?

Thanks again, Lew. Lots of great information.
 
L

Lew

Jason said:
One last question - a controller doesn't necessarily have to be a
separate class, does it? Can it be part of (from a class perspective
- not a logical one) the model or view - especially if it doesn't do a
whole lot?

You should be more precise in terminology. Let me rephrase your question; you
tell me if I did it wrong: "Does one need to implement the controller in a
separate component from the view or model?"

The "controller" is a concept. As such, it is distinct from the "model" and
"view" irrespective of implementation.

<http://en.wikipedia.org/wiki/Model-view-controller>
many of the links at the bottom of that page address your specific questions.

Google on "model-view-controller". There are many variants on the theme.
One, whose name escapes me and I just plain don't feel like doing all the
googling here, represents fractally more detailed controllers each with its
own mini- (micro-, pico-, femto-, ...) MVC loop.

Marty Hall [1] suggests implementing the controller as a distinct method in a
backing bean, if you're programming for JSF [2]. Other parts of the bean
implement the model, or part of it. I've done that; I've also implemented
controller functionality in a separate class, or even several separate
classes, using JSF.

Struts [3] uses a separate controller servlet that the application programmer
treats as a black box. Each Action class in Struts implements a method such
as execute() to handle the action for a screen. That method is the controller
for that screen. Or is it the logic? It's a floor wax /and/ a delicious
dessert topping!

Notes:
[1] <http://www.coreservlets.com/JSF-Tutorial/>
[2] <http://java.sun.com/javaee/5/docs/tutorial/doc/JSFIntro.html#wp114889>
<http://myfaces.apache.org/>
[3] <http://struts.apache.org/>
 
J

Jason Cavett

Jason said:
One last question - a controller doesn't necessarily have to be a
separate class, does it? Can it be part of (from a class perspective
- not a logical one) the model or view - especially if it doesn't do a
whole lot?

You should be more precise in terminology. Let me rephrase your question; you
tell me if I did it wrong: "Does one need to implement the controller in a
separate component from the view or model?"

The "controller" is a concept. As such, it is distinct from the "model" and
"view" irrespective of implementation.

<http://en.wikipedia.org/wiki/Model-view-controller>
many of the links at the bottom of that page address your specific questions.

Google on "model-view-controller". There are many variants on the theme.
One, whose name escapes me and I just plain don't feel like doing all the
googling here, represents fractally more detailed controllers each with its
own mini- (micro-, pico-, femto-, ...) MVC loop.

Marty Hall [1] suggests implementing the controller as a distinct method in a
backing bean, if you're programming for JSF [2]. Other parts of the bean
implement the model, or part of it. I've done that; I've also implemented
controller functionality in a separate class, or even several separate
classes, using JSF.

Struts [3] uses a separate controller servlet that the application programmer
treats as a black box. Each Action class in Struts implements a method such
as execute() to handle the action for a screen. That method is the controller
for that screen. Or is it the logic? It's a floor wax /and/ a delicious
dessert topping!

Notes:
[1] <http://www.coreservlets.com/JSF-Tutorial/>
[2] <http://java.sun.com/javaee/5/docs/tutorial/doc/JSFIntro.html#wp114889>
<http://myfaces.apache.org/>
[3] <http://struts.apache.org/>

Haha, thanks for all the links. Don't worry - I've been Googling a
lot to make sure I understand it. Unfortunately, there's so much
information out there, and not everybody understands MVC the same way,
that it can get confusing.

I've been reading in the wikipedia site. Thanks for the other
information.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,235
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top