Home > Archive > Software Engineering > October 2006 > Starting from scatch - GUI MVC implementation?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Starting from scatch - GUI MVC implementation?
|
|
| Timasmith 2006-10-23, 4:00 am |
| Next attempt to get down a smooth, patterned implementation of user
interface interaction code. This is a fat client (swing but thats
neither here nor there).
My last attempt had the following general design.
a) A controller which instantiated the Application (frame).
b) A controller per form.
c) Forms inherited a lot of code to layout the controls and bind them
to a business object.
d) Forms also had a mediator which the controller would subscribe to
certain event messages.
e) The toolbar and menu would send event messages.
f) Services provided the facade to the CRUD processing data access
layer (some business logic there to).
g) An action class per form which had all the code which executed for
interactions.
So it worked, but as Martin Fowler would say there was a bad smell
coming from somewhere.
The action class was extremely long - essentially one action per
toolbar/menu item.
The controller had a mismash of everything that was used when starting
the main application from. Many of the controller methods were
eventually called by the action class.
You might say once the action implementation started, OOP was left in
the dust for a mass of functions that executed on the various trees,
tables, and any other menu item.
The biggest challenge seems to be separating concerns. The mediator
helps a lot but has limitations. The worst is that it knows nothing of
the events and objects sent or received. So I might have:
Mediator
receive(Event, Object)
subscribe(Event)
MenuItem implementation
mediator.receive(Event.EXECUTE, Action.DELETESELECTED)
Controller implemenetation
on receive event
if event = Event.EXECUTE
if action = Action.DELETESELECTED
access the currently selected tree/table
get the selected items
delete them all
This is not great for the controller.
a) It had to cast a generic object to an Action
b) It then had to go get the selected items (a bit late now)
in practice b) is not really late - it all happens instantaneously but
it still smells late
Now lets say we have a tree and table. Neither should know about the
other. Selecting a node in the tree changes the contents of the table.
So the controller implementation
on select node
get selected nodes
mediator.receive(Event.TREENODESELECTED, ObjectsFromNodeList)
So the message to the mediator contains the user objects, so the target
does not have to do any work. But it still has to cast the Object into
a ObjectsFromNodeList which creates a nasty change on the type of
object and corresponding if statement.
So perhaps the mediator should have more specific methods
Mediator
receiveObjectsFromNodeList(ObjectsFromNo
deList)
subscribeObjectsFromNodeList()
hmm, that smells just as bad.
Its all very tricky, but I know there is a way, I can feel it.
Here is the challenge. 1000 forms. 1000 menu items. 1000 toolbar
actions. 10000 interactions between menus, toolbars, trees, forms,
controls.
How do you do it without create a morass of unmaintainable code.
| |
|
| Timasmith wrote:
> a) A controller which instantiated the Application (frame).
> b) A controller per form.
> c) Forms inherited a lot of code to layout the controls and bind them
> to a business object.
> d) Forms also had a mediator which the controller would subscribe to
> certain event messages.
> e) The toolbar and menu would send event messages.
> f) Services provided the facade to the CRUD processing data access
> layer (some business logic there to).
> g) An action class per form which had all the code which executed for
> interactions.
>
> So it worked, but as Martin Fowler would say there was a bad smell
> coming from somewhere.
He would start again using Test Driven Development, and emergent design.
When I have done that, targeting MVC, I did not build the MVC part first,
then hang all the details off it. Instead, I wrote simple GUI code and
refactored it until MVC emerged.
And MVC does not mean "The View observes the Model"; not in bulk. It means
"individual elements in the View observe individual elements in the Model".
And so on. That prevents a lot of duplication, which I'm sure you have.
(Use Jemmy for brute-force TDD on Swing, BTW...)
> Here is the challenge. 1000 forms. 1000 menu items. 1000 toolbar
> actions. 10000 interactions between menus, toolbars, trees, forms,
> controls.
>
> How do you do it without create a morass of unmaintainable code.
Observer Pattern means all Forms use one mechanism to observe their target
elements in the Model...
--
Phlip
[url]http://www.greencheese.us/Z Land[/url] <-- NOT a blog!!!
| |
| Karsten Lentzsch 2006-10-30, 9:59 pm |
| Timasmith wrote:
> Next attempt to get down a smooth, patterned implementation of user
> interface interaction code. This is a fat client (swing but thats
> neither here nor there).
>
> My last attempt had the following general design.
>
> a) A controller which instantiated the Application (frame).
> b) A controller per form.
> c) Forms inherited a lot of code to layout the controls and bind them
> to a business object.
> d) Forms also had a mediator which the controller would subscribe to
> certain event messages.
> e) The toolbar and menu would send event messages.
> f) Services provided the facade to the CRUD processing data access
> layer (some business logic there to).
> g) An action class per form which had all the code which executed for
> interactions.
> [...]
The big picture I use is: separate the domain from the rest,
and separate the views from the presentation logic. So we
get either Model-View-Presenter (MVP) or "Presentation Model".
In both cases you end up with a domain layout that most
teams can manage, a quite thin GUI layer with "dumb" views;
and the remaining complexity and problems sit in a middle
layer of presenters or a graph of presentation models.
I recommend "Presentation Model" (PM) to teams that can
manage the data binding between the PM and the views.
That requires some skills to understand the synchronization
and at least some team members need to know how to debug
the implicit operations that come with a data bindng.
For the rest I recommend to use the simpler MVP.
To further remove complexity from the middle layer,
try to move larger operations to a service layer,
for example for data lookup, search, server communication.
As application infrastructure I'm satisfied with an
experimental implementation of the JSR 296 "App Framework".
It lays out how to manage resources, actions, preferences,
and how to start an app, and how to shut it down.
To make the view layer really thin, I use a desktop lib
that manages how views are displayed. And I take care
about a consistent meta design that is in a dialog lib.
-Karsten
|
|
|
|
|