Refactoring toward MVC

0 views
Skip to first unread message

Dave Benjamin

unread,
Nov 26, 2003, 12:33:29 PM11/26/03
to
The thread about refactoring a Swing UI monster reminded me of a more
general problem that I am trying to solve, and I was wondering if any of you
have advice on a suitable process for pushing UI code toward a
model-view-controller architecture.

For instance, I have an object that I initially intended to represent a
view, but I didn't anticipate how complex it would become, and even though I
made a deliberate effort to separate the model in this application, a sort
of presentation-oriented model crept into the view over time. In addition,
I'm still trying to get my head around MVC, and when I started writing this
application, I was very uncertain as to what a "controller" was, and
therefore didn't separate the controller aspects out of this object.

So, what can I do now? What would be a good series of steps to refactor it
toward MVC? I haven't attempted this yet, but here's a rough idea:

1. Find groups of event handler methods and extract one or more controller
classes, perhaps segregating them by which broadcasting object(s) they
listen to, or which listener interface(s) they implement.

2. Isolate any state and separate it into separate model classes. This seems
like another "extract class" operation, but the intricacies are much more
complex. Where do you draw the line between a view's data and a model's
data?

3. Rewrite the code that builds the view object so that it links all of
the extracted classes together in a modular fashion.

4. Introduce the observer pattern to eliminate the view's knowledge of the
controllers and the models' knowledge of the view or controllers.

Has anybody ever attempted this? Any feedback would be appreciated...

Thanks,
Dave

--
.:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
: d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :

Tsolak Petrosian

unread,
Nov 26, 2003, 5:23:54 PM11/26/03
to
Dave Benjamin <ra...@lackingtalent.com> wrote in message news:<slrnbs9pd0...@lackingtalent.com>...


Every time someone mention MVC something triggers in me:)
I'll repeat it again.
MVC should only be used in tookits like Swing (even there it's not that important).
Never try to apply MVC to any GUI applications!

Tsolak Petrosian

Dave Benjamin

unread,
Nov 26, 2003, 7:58:09 PM11/26/03
to
In article <a052897d.03112...@posting.google.com>, Tsolak Petrosian wrote:
> Every time someone mention MVC something triggers in me:)

Usually it triggers something in me as well - my suspicion that the someone
in question is not really talking about MVC, even though he or she may
honestly believe it. =)

> I'll repeat it again.

Okay, this is the first time for me.

> MVC should only be used in tookits like Swing (even there it's not that important).
> Never try to apply MVC to any GUI applications!

What if a portion of your application requires UI components that your
platform does not provide? How would you determine what belongs in a toolkit
(and therefore could benefit from MVC, even though it's not that important)
and what is part of an application?

I'm not the first to promote MVC as the one-true-way to write GUI toolkits
*or* applications, but it seems like there must be some benefit or people
wouldn't be so crazy about it. The need to separate the model from the view
is obvious, I think. But I would still like to understand MVC better, and
how to go about realizing MVC in an existing application.

Even if it's never to be done, as you say, it's still an interesting puzzle:
How do you get there from here?

Richard MacDonald

unread,
Nov 27, 2003, 12:21:56 AM11/27/03
to
Dave Benjamin <ra...@lackingtalent.com> wrote in
news:slrnbs9pd0...@lackingtalent.com:

> The thread about refactoring a Swing UI monster reminded me of a more
> general problem that I am trying to solve, and I was wondering if any
> of you have advice on a suitable process for pushing UI code toward a
> model-view-controller architecture.
>
> For instance, I have an object that I initially intended to represent
> a view, but I didn't anticipate how complex it would become, and even
> though I made a deliberate effort to separate the model in this
> application, a sort of presentation-oriented model crept into the view
> over time. In addition, I'm still trying to get my head around MVC,
> and when I started writing this application, I was very uncertain as
> to what a "controller" was, and therefore didn't separate the
> controller aspects out of this object.

(Preface: There are those who don't like MVC. Still waiting for their
alternative that isn't a big ball of mud. Yeah, stick that SQL string in
the TextField subclass or GodController :-)

First point: MVC and MVP are poorly written up. For such important
patterns, this is amazing, but its true. You probably only get MVC/MVP by
reading a little then writing code to figure it out for yourself. For
example, hardly any MVC/MVP articles mention Adapters, yet they are very
helpful. And hardly any MVC/MVP articles mention using the Composite
pattern for the V and the C/P, yet they are very helpful. I had to find
this out by myself.

Second point: MVC is obsolete. It was relevant when the View classes were
very new, i.e., they basically did nothing but draw themselves and you
had to write your own event loop. As the View classes grew more
sophisticated, they started to encompass the Controller aspects as well.
So today we have both VC contained within the GUI classes. This led to
the Presenter over the Controller and the MVP over the MVC. You can find
one or two MVP articles in the Smalltalk world (Taligent had a good
article, but still missing much detail.) Don't get confused by the MVC
you hear talked about in the Java/Web world. They call it MVC2, if I
remember right. That's just a pattern for dealing with state and web
limitations. Basically useless unless you're working with browsers.

Third point: I believe MVP should be hierarchical rather than
"triangular". The MVP event loop goes from Model to View to Presenter to
Model. I believe this is inferior. I implement it as Model<->Presenter<->
View. IOW, the Presenter is the sole connection between Model and View.
Everything must go through the Presenter. I confess I've probably never
written a "correct" MVP so my comparison may be biased, but in my case a
little ignorance was a good thing when I wrote my first MVC/MVP and I did
it with a strict hierarchical layer and liked it. Never found a single
reason why its not better.



> So, what can I do now? What would be a good series of steps to
> refactor it toward MVC? I haven't attempted this yet, but here's a
> rough idea:

We really need a better description of your problems right now. Sure we
can respond to the following bullet points, but we need more context for
your problems. For example, you say your model has become presentation
oriented. Does this mean your model knows about its display? If so, then
your first refactoring is to remove this. You can (a) place the burden on
the presenter class, or (b) write an Adapter to sit in-between the Model
and Presenter and put the code there. Things like that.

A big issue before continuing: Does your Model "independently" issue
events that the display must update on, or can your Presenter "know" all
possible updates required when it makes a change to the Model. IOW, are
there any sources of events outside your particular user, and/or is your
model sufficiently complicated so that it alone should be responsible for
cascading all the changes its undergoes when it receives a change message
from the Presenter?

If the former, then you'll need a general event linkage between your
model and display. If the latter, the model can remain dumb and the
presenter can take up the slack.

0) Baby steps man, baby steps. Then take lots of them :-)



> 1. Find groups of event handler methods and extract one or more
> controller
> classes, perhaps segregating them by which broadcasting object(s)
> they listen to, or which listener interface(s) they implement.

Without context, I cannot say. What are these methods *doing*? Its sounds
like this is a "secondary" issue, rather than fixing the true problem,
but I'm guessing.



> 2. Isolate any state and separate it into separate model classes.
> This seems
> like another "extract class" operation, but the intricacies are
> much more complex. Where do you draw the line between a view's
> data and a model's data?

There is model state and display state. The model state should be
straightforward, i.e., all about the model and nothing about anything
displaying it. The display state belongs in the Presenter(s) class. As
for drawing the line, don't get distracted by the fact that the GUI
classes have state. That is the C migrating into V issue I mentioned
above. The GUI classes *need* their own state, but that state has nothing
to do with the Model state. Where the two states need to be in sync, then
*duplicate* the state and don't worry about it, with the Presenter being
responsible for maintaining the sync. My paragraph is bouncing around a
bit, sorry, but there should be absolutely no difficulties in drawing
this line, so I'm not sure what to say.



> 3. Rewrite the code that builds the view object so that it links all
> of
> the extracted classes together in a modular fashion.

Sure. Modular is good, even though it may lead to more complicated
"configuration" code during the initialize.

My View objects consist of low-level GUI objects plus a single View
object that instantiates and configures all the low-level GUI objects.
This View object is responsible for creating a Window/Frame or Panel.
That is all it does. My Model objects deal only with Model stuff. I
usually can avoid even the Model event stuff because I shove it in the
Presenter instead. (Simple Models only, of course.) My Presenter is
everything else required to make it work. As the Presenter gets
overburdened, I split off sub-Presenters and let the multiple Presenters
work in coordination.



> 4. Introduce the observer pattern to eliminate the view's knowledge
> of the
> controllers and the models' knowledge of the view or controllers.
>

IMHO, the View should know nothing about the controllers. It may be coded
to send specific events to a Presenter, but it doesn't need to. Better to
have the Presenter stick its nose into the View and register the events
its needs. The Model should absolutely not know a thing about the view or
controllers. Have the Model generate events as needed, then (my
hierarchical MVP rather than the triangular MVP, so the following is
IMHO) have the Presenter register with the Model for these events,
interpret them, then forward to the View as needed.

Also look at Adapters. Adapters can be thought of as a mini Presenter
between a particular Model class or attribute and a particular gui
widget. You'll find that the Presenter does the same thing/abstraction in
slightly different ways over and over again between the Model and View.
So create a separate Adapter class for this abstraction, instantiate it,
pass the Model and View subcomponents to the Adapter, then delegate the
management to the Adapter. The Adapter points back to the Presenter as
necessary.

Tsolak Petrosian

unread,
Nov 27, 2003, 12:55:05 PM11/27/03
to
Dave Benjamin <ra...@lackingtalent.com> wrote in message news:<slrnbsajeq...@lackingtalent.com>...

> In article <a052897d.03112...@posting.google.com>, Tsolak Petrosian wrote:
> > Every time someone mention MVC something triggers in me:)
>
> Usually it triggers something in me as well - my suspicion that the someone
> in question is not really talking about MVC, even though he or she may
> honestly believe it. =)
>
> > I'll repeat it again.
>
> Okay, this is the first time for me.
>
> > MVC should only be used in tookits like Swing (even there it's not that important).
> > Never try to apply MVC to any GUI applications!
>
> What if a portion of your application requires UI components that your
> platform does not provide? How would you determine what belongs in a toolkit
> (and therefore could benefit from MVC, even though it's not that important)
> and what is part of an application?

There are set of general, reusable UI components which alsmost all
toolkits contain, if you feel like to make your own go ahead and make
it that same way as other UI are in particular toolkit, but this has
nothing to do with UI application.
The UI application is concret implementation of composing sets of
smaller UI components each modeled as black box (which includes logic
and state) of concrete inputs/outputs plus graphical object
representation and can be functional by their one.
The toolkit UI component is graphical object plus abstract model, and
only functional when used in above applications.


>
> I'm not the first to promote MVC as the one-true-way to write GUI toolkits
> *or* applications, but it seems like there must be some benefit or people
> wouldn't be so crazy about it. The need to separate the model from the view
> is obvious, I think. But I would still like to understand MVC better, and
> how to go about realizing MVC in an existing application.
>
> Even if it's never to be done, as you say, it's still an interesting puzzle:
> How do you get there from here?

What people think is not important, people were very crazy about
waterfall and are still crasy about EJB and OO databases.
I think MVC has to be an antipattern, because even thought speratation
of model from view seems logical but it still doesnt offer any
benefits since we still end up privately using both model and view
implementations inside once class even in case of toolkits we could
have done it like MFC did just have abstract View with abstract model
callback functions.

Tsolak Petrosian

Harry Erwin

unread,
Nov 27, 2003, 4:26:34 PM11/27/03
to
Richard MacDonald <macdo...@worldnet.att.net> wrote:

My first exposure to MVC was when I was writing Smalltalk code back in
1987. It was very hard to understand from the Smalltalk-80 books.

>
> Second point: MVC is obsolete. It was relevant when the View classes were
> very new, i.e., they basically did nothing but draw themselves and you
> had to write your own event loop. As the View classes grew more
> sophisticated, they started to encompass the Controller aspects as well.
> So today we have both VC contained within the GUI classes. This led to
> the Presenter over the Controller and the MVP over the MVC. You can find
> one or two MVP articles in the Smalltalk world (Taligent had a good
> article, but still missing much detail.) Don't get confused by the MVC
> you hear talked about in the Java/Web world. They call it MVC2, if I
> remember right. That's just a pattern for dealing with state and web
> limitations. Basically useless unless you're working with browsers.
>
> Third point: I believe MVP should be hierarchical rather than
> "triangular". The MVP event loop goes from Model to View to Presenter to
> Model. I believe this is inferior. I implement it as Model<->Presenter<->
> View.

So the Presenter is conceptually an association class between Model and
View?

> IOW, the Presenter is the sole connection between Model and View.
> Everything must go through the Presenter. I confess I've probably never
> written a "correct" MVP so my comparison may be biased, but in my case a
> little ignorance was a good thing when I wrote my first MVC/MVP and I did
> it with a strict hierarchical layer and liked it. Never found a single
> reason why its not better.
>
> > So, what can I do now? What would be a good series of steps to
> > refactor it toward MVC? I haven't attempted this yet, but here's a
> > rough idea:
>
> We really need a better description of your problems right now. Sure we
> can respond to the following bullet points, but we need more context for
> your problems. For example, you say your model has become presentation
> oriented. Does this mean your model knows about its display? If so, then
> your first refactoring is to remove this. You can (a) place the burden on
> the presenter class, or (b) write an Adapter to sit in-between the Model
> and Presenter and put the code there. Things like that.

One Adapter? or many?

>
> A big issue before continuing: Does your Model "independently" issue
> events that the display must update on, or can your Presenter "know" all
> possible updates required when it makes a change to the Model. IOW, are
> there any sources of events outside your particular user, and/or is your
> model sufficiently complicated so that it alone should be responsible for
> cascading all the changes its undergoes when it receives a change message
> from the Presenter?

Independently, but sensitive to the Presenter.


--
Harry Erwin <http://www.theworld.com/~herwin/>

Richard MacDonald

unread,
Nov 28, 2003, 11:37:33 AM11/28/03
to
her...@theworld.com (Harry Erwin) wrote in
news:1g53fcb.pcjpsm1onu7i8N%her...@theworld.com:

> Richard MacDonald <macdo...@worldnet.att.net> wrote:
>
>
> My first exposure to MVC was when I was writing Smalltalk code back in
> 1987. It was very hard to understand from the Smalltalk-80 books.

Ah, but if you know Smalltalk from 1987, you're already an expert :-)



>> Third point: I believe MVP should be hierarchical rather than
>> "triangular". The MVP event loop goes from Model to View to Presenter
>> to Model. I believe this is inferior. I implement it as
>> Model<->Presenter<-> View.
>
> So the Presenter is conceptually an association class between Model
> and View?

I wouldn't call it that, since an association class has static domain
model connotations for me. I prefer to think of it as "everything else
required to make a Model and View work in a particular way" :-) IOW, you
have a Model that knows only about domains and you have a View that is
nothing but a big initializeDumbWidgets method; now write a class that
uses them.

>> [...]For example, you say your model has become


>> presentation oriented. Does this mean your model knows about its
>> display? If so, then your first refactoring is to remove this. You
>> can (a) place the burden on the presenter class, or (b) write an
>> Adapter to sit in-between the Model and Presenter and put the code
>> there. Things like that.
>
> One Adapter? or many?

Many. You can go whole hog and write in a composite sense: One high-level
ModelAdapter for the entire Model, then the ModelAdapter intercepts all
traversal methods and answers smaller ModelAdapters that wrap the smaller
Model objects. Kinda like a SQL view on the data tables. Note that I have
never found a need for such an approach, I'm just suggesting it as
something to think about. Its also useful as a refactoring step to remove
the view-knowhow from the model. Maybe these adapters are the end of the
refactoring; maybe they then get refactored away again.

>>
>> A big issue before continuing: Does your Model "independently" issue
>> events that the display must update on, or can your Presenter "know"
>> all possible updates required when it makes a change to the Model.
>> IOW, are there any sources of events outside your particular user,
>> and/or is your model sufficiently complicated so that it alone should
>> be responsible for cascading all the changes its undergoes when it
>> receives a change message from the Presenter?
>
> Independently, but sensitive to the Presenter.

Ah. Think hard about this. "Independently" means that something happened
that was not caused by the presenter. And "sensitive to the presenter" is
a red flag for problems. Simply put, it cannot be. Instead, you'll have
to have your model firing *all* events without regard for presenter
context, then have the presenter decide whether or not to process the
event further. Otherwise you'll never separate presenter-knowhow from
your model

Dave Harris

unread,
Nov 29, 2003, 5:30:00 AM11/29/03
to
her...@theworld.com (Harry Erwin) wrote (abridged):

> So the Presenter is conceptually an association class between Model and
> View?

I tend to think of the Presenter as being the actual thing; it happens to
be factored internally into two components that are more reusable.

-- Dave Harris, Nottingham, UK

Harry Erwin

unread,
Nov 29, 2003, 11:15:54 AM11/29/03
to
Dave Harris <bran...@cix.co.uk> wrote:

OK, here's a segue. I've got good evidence that bats live in their
internal model, which is asynchronously updated using sounds and other
sensory inputs and is used as the basis for controlling their behavior
out in the real world. Your Presenter is the thing that translates VC =
sensory stimuli into the Model (and vice versa). In vertebrates, a lot
of that seems to be handled using the cerebellum, and isn't
well-understood. A better understanding of how that takes place might
help us in OO.

Reply all
Reply to author
Forward
0 new messages