Design: help on CMV refactoring in a simple form app?

F

Francesc

Hi,

After some years programming libraries and web based applications I'm
trying to program my first not-silly windows application (something
similar to an editor but just to annotate text lines).

After some trials just putting some code directly at the control events
I tried to refactorize a little. But after read some documents on CMV
(Controller-Model-Viewer) pattern I spent all this week trying
unluckily to use it.

First subject:
==============

I'm not sure to understand completelly how this pattern is implemented
in real *code*. For example:

- Is the Controller the winForm? I thought yes, because it is which
receives the user event, it isn't?

- Is the Viewer also the winForm? I thought yes, because it is who
display the model representation.

But, How the model informs to the Viewer that it must refresh the view
(in this case the RichTextBox).

Second subject:
===============

A less general problem. I have coded the next "big" classes:

* zApplication: It's a blackbox that models all the logic and behavour
of the application. All control events are pass through to methods of
this object.

(Menu->OpenFile) event = { zApplication.OpenFile(<????>);}

Inside this zApplication I have two objects:

* zDocument: It's the model of the content that it's edited. It has
some properties (CurrentLine, ...) and methods (MoveDownCurrentLine or
DeleteCurrentLine).

(KeyDown) event = { zDocument.MoveDownCurrentLine; }
(KeyEnter) event = { zDocument.DeleteCurrentLine; }

* zViewer: It's a dumm class that returns the "graphical" (in fact it
is a RTF representation) version of zDocument: the text with numbered
lines and the background of the CurrentLine colored yellow.

richTextBox.RTF = zViewer.RenderedDocuement;

Problem:
========

To "copy" the updated RTF rendering I use the previous code, but I'm
not happy that the "controller" (the winForm) is who handles the
updating.

Another problem is that zDocument must return bools for every command
in order to inform the "controller" that the command implies a refresh,
and "controller" must check thems all the time, using code like:

if (zDocument.MoveDownCurrentLine== true)
{
zViewer.UpdateRendering(zDocument);
RefreshRTF();
}

private RefreshRTF();
{
richTextBox.RTF = zViewer.RenderedDocument;
}


Someone has been so nice to read as deep in this awfull english
message?
Some of the nice guys who did know some way to refactor this design in
order to be cleaner and/or most similar to the CMV spirit?

Thanks very much, I'm really lost... :-/


[Note: The "pseudo"-code was write as an indication, sure that it has a
lot of syntax errors not useful in this thread.]
 
J

Jeff Louie

The simplest approach is M-VC or ENGINE-INTERFACE.

http://www.geocities.com/Jeff_Louie/OOP/oop3.htm

In Objective-C I use a simple version of M-V-C where the controller owns
the
model and the view. All communication goes throught the controller so
that the
controller gets the data from the view, updates the model and then
updates the
view. Events go to the controller.

If the interactions are too complex the Mediator pattern may help.

http://en.wikipedia.org/wiki/Mediator_pattern

Sometimes I have written a manager class that updates the view and binds
to the
model. The manager class can control paging for instance.

Regards,
Jeff
 
F

Francesc

Hi Jeff,

Thanks for your reply, your article on "Model--View/Controller" was
quite clear. It seems that my former approach was near enough,
zApplication as the Model and the winForm as the the View/Controller.

I now see that my problem is inside the Model, let's zoom in it:

- I use this Model to own some properties related to the dynamic state
of the application: like fileName of the document that is tagged,
wrapping lines mode, etc... Is this right?

- this Model also owns a "document" object related to the text that is
been tagged: like a array of lines, an index of the line been tagged,
.... and it performs the operations in the text.

- and finnaly this Model owns a "renderer" object (that I called
incorrectly "viewer") that needs to read the "document" in order to
obtain an RTF representation to update the richTextBox that is inside
the webForm (that is in the "view/controller" object).

My last question is: Is a good idea that the Form owns a "document" and
a "renderer"?

[WinForm]
+-------------------+
| [ Document ] |
| |
| [ Renderer ] |
| |
| richTextBox |
+-------------------+

I have some problems getting a clean dessign, because I need:

- that Document alert to the WinForm that the content has been changed
- that the Renderer can read Document in order to obtain a new RTF
representation
- and that the WinForm knew when update the richTextBox.

Thanks to you and to anyone that can bring some more light .. :)

Francesc
 
J

Jeff Louie

Well I hesitate to answer since I do all my database work now with a RAD
database tool. But then I am old enough to have written wholesale
billing
software and custom file systems in Turbo Pascal and loaded boot drivers
onto a PDP11.

I would design the Model to be totally generic so that it knows nothing
of the
view or persistence mechanism. So I am not sure it is a good idea that
the
Model knows how to open a file. The View-Controller can read and write
the
Model to a file perhaps by serializing the Document object to a file,
or it
could read and write RTF. So there might be a need for a
Model.GetDocument() and Model.SetDocument (or a Document property) and
a Model.NewDocument() method. There would be a need for a Model.ToRTF()
method and perhaps a Model.FromRTF(). Or perhaps extenally only a RTF
property so that the Document is _not_ visible outside of the Model.

It is fine that there is a current line property in the Model, but this
has
nothing to do with the current line in the View-Controller! You should
be able
to run the Model class from a command line and set the current line to 3
and
then delete the current line or delete a range of lines. The console
class could
even have a parser that allowed one to edit the document from the
command
line, open a file and save to a file. So I think I would first build a
Model class
that I could run from a command line. Only then would i worry about the
View-Controller.

In a more complex application you could bind a richTextBox in the
ViewController to the Model so that the richTextBox is notified of any
change
in the Document. Still the Document must not be aware of any of the
specifics
of the view such as the implementation of the richTextBox. So you might
need to define an interface INotifyChange(). The richTextBox implements
INotifyChange. The richTextBox would need to register an interest in the
event or interface to the Model. The Model would keep an array of
interested
listeners or event subscribers. The model could notify all interested
listeners
when the Model state changed. Things get more difficult if you get into
circular notifications. Perhaps Joanna can be of help in that regard.

Finally you can have a mediator or manager between the Model and
controls.
The Model notifies the manager and the manager changes the view.

Regards,
Jeff
 

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