Patterns and best practise for model/view/controller separation?

E

elvis_the_king

Hi all,

I have quite some design experience on other platforms and especially
with web applications. Now I'm about to design a .NET application and
am a little stuck as I am trying to apply my "habits" of separating
model, view and controller. Either that is the totally wrong approach
or I am not familiar enough with the platform to make it :).

By now, I've already written some model classes and test cases. In that
simple case, the "controller" is nothing more than the logic that
creates the right instances of models, connects them and calls some
business methods on them, validating the results.

Now as it comes to adding a GUI and responding to user input, I was
hoping that there is something like the "blueprints" with J2EE, that
is, some patterns as design recommendations on how to sort things out;
or maybe you can share your thoughts and experience with me?

I'll try to describe the problems I've run into so far; that should
make it easier to reply as the question will be less abstract :)

For every model, I will have one or more views to display the models.
These views are subclasses of System.Windows.Forms.Form.

Basically - how to separate controller and view? It seems to me that
it's always the Form class that reacts on user input; but maybe that is
just because the IDE/designer suggests that? I assume it is possible to
move that code to some "controller" class (probably somehow using the
properties of the form controls?) - but is that a good idea? Shouldn't
I just keep it as suggested?

Next, is it right to create a new instance of a certain view class (the
form) for every model I want to display? Or should I avoid creating too
many instances of the form class - that would mean I should instantiate
every form only once and use something like the flyweight pattern to
provide the view with the model it is supposed to display?

If several form instances are ok and I keep the controller logic in the
form class as well, one approach would be to simply pass the form its
model in the constructor like:
static void Main() {
Model m = new Model();
View v = new View(m); // View subclasses System.Windows.Forms.Form
Application.Run(v);
}
The view would then - maybe in an btnOK_Click handler - update the
model, maybe like
void button1_Click(object sender, System.EventArgs e) {
myModel.doSomeBusiness(textBox1.Text);
}
Is that a good approach? Clearly, what button1_Click does is the job of
a controller.

One more problem with the "pass model to form/view constructor"
approach is when instantiating new models: Sometimes I need to display
a form to collect some user input; that user input is necessary for
creating the new model instance. Later on, the same view class is
supposed to provide the means of manipulating the model again.

I feel it's not a good idea let the form be constructed without a model
and add another method like "createAModelFromInput()" that would build
the "new" model for me.

Thus, another way would be to have something like (informal notation)

class Controller {
newModelUseCase {
v = new View()
v.display()
// extract "pure data" from view here
m = new model(data extracted)
}

updateModelUseCase {
m = someModelIAlreadyGot;
v = new View()
// extract all data from model here
// populate v with the data
v.display()
}
}

Now that is clearly too much for a controller - the whole "extract data
from model and populate view" thing is the view's responsibility.

As a side note, with my specific application requirements I would
benefit if the whole create new model / update model could be generic.
I know that there will be future extensions to my application that will
bring new models with appropriate views, so it would be elegant to keep
that part of code arbitrary enough to work with such extensions.

As to updating the view upon model state changes, that's probably no
problem with a standard observer pattern approach where the view might
(pherhaps in its constructor) subscribe for model notifications. The
only thing I'm a little afraid here is that in the future, threading
problems might arise (what if the model changes in a non-GUI thread and
does the notification from there?).

I'm happy you read until here :) Again, point me to some recommended
approaches/patterns/best practices if there are some :) - I found
nothing that satisfies me :).

Please reply to the group - I will follow things here.

Thanks in advance,
Matthias
 
E

elvis_the_king

Hi Bart,

thanks a lot for pointing me to that one. I hope that this is still the
right group to discuss the issue :)

I downloaded the UIPAB and skimmed the included quick start "wizard"
example as well as some docs. The whole thing reminds me of Struts (a
Java framework); it was not too hard to get a rough idea of the big
picture.

Honestly, I think applying UIPAB to my application would be overkill
and distract me from the *real* problems I need to solve :). However, I
tried to answer my questions myself from looking at the UIPAB code. A
big part of the facilties it provides (namely persistence of state and
detailed control flow) are not important for me, so I can skip them.

Now if I get things right, my "model" is the state in UIPAB terms. No
matter how they select and instantiate the "right" controller class, I
end up with an instance of a controller class that keeps a reference to
that state. The view (a form) is displayed and has a reference to that
controller.

Now what puzzles me is that in the "UIProcessQuickstarts_Wizard"
example, there is still a helper class (PaymentInfo) that is just a
bunch of public string members. When the form wants to display the
model's data, it asks the Controller for the current model state
(GetPaymentInfo()). The controller takes the PaymentInfo (a pure
data-carrying class) from the state (the model) and returns it to the
view. The view reads all the fields from the PaymentInfo and updates
its controls.

Now the other way round - click the "next" button on the form. It
triggers the event code in the form class. This code reads all the
values from all the controls the form displays, wraps it up in a
PaymentInfo and asks his controller for updating the model:
myController.UpdatePaymentInfo(paymentInfo). After that, it's still the
event code in the form triggering myController.ShowNextStep().

Probably because I come from a web application background, it seemed
odd to me that it is the form receiving the event, calling an
appropriate method (of its own choice) on the controller - with the
presentation layer being a web browser, usually there will be a
"common" entry point for all requests directly into the controller, and
the controller has to dispatch to the right method.

The other thing is the cumbersome way an extra data-carrying
"no-brainer" class is required to pass data around between the model
and view (through the controller). Anyone wants to comment on that one?
:)

Does anyone mind to explain how they separate things ;)?

Best regards,
Matthias
 

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

Top