[TFUI] The MVP pattern and loose coupling between view/presenter and presenter/model
Ed Howland <[email protected]> Wed, 14 Sep 2005 18:51:25 -0500
| Newsgroups | gmane.comp.programming.test-first-user-interfaces |
|---|---|
| Message-ID | <[email protected]> |
OK, say you have a dialog, (be it ever so humble,) and you have
implemented the presenter and the view such that only primitive things
are passed from the presenter to the view (strings, ints, lists,
dates.) This is good because you can test the presenter with mocked
views and the mocks are fairly simple.
What I'm wondering is, can there ever be a scenario in which higher
order objects (from the model) are passed between presenter and view?
Consider adding some more functionality to the dialog. I want to add a
[Add New] button which invokes a new form whose job it is to return a
newly populated object from one of the model's classes. Once I have
this object, I want to add it to the current collection which is being
shown on the dialog. Said collection being maintained in the model (or
presenter.)
This seems straightforward, till you follow the chain to the end.
First connect the click event of the [Add New] button to a method on
the presenter which launches the new dialog. Then let the method
handle construction and invocation of the new view for AddNew form.
But wait! You are in danger of violating the "separation of concerns"
rule. In my classes, I want only the view to handle UI creation and
manipulation. Even message boxes (errors, info) are implemented within
the view through a view interface method. No views in the model except
those view interfaces passed in from the outside. (Our mocks during
testing and real UI elements during non testing runs.)
But I can't get this view to invoke my Add New dialog for me without
passing in and out the constructed and populated model object to my
presenter for insertion into the collection. Which violates the "only
pass primitive things" rule.
Another possibility is to construct the new view/presenter/model
object triad within the current presenter. The model object wants to
be born and added to his siblings within the presenter (if that is how
this kind of presenter works.) But who has the responsibility of
creating the UI to control our user to populate the model object?
Passing this triad to the view is even less primitive than passing the
model object was.
If I let the presenter do it, then it becomes harder to test. I can
imagine mocking the new presenter (and possibly its new view) Implying
extracting the Add New presenter into an interface. I haven't gone
this far yet, so I'm unsure.
Or should there be some underlying layer whose job it is to construct
these triads? In this case, perhaps the presenter has been constructed
with a reference to the object who constructed him or some other
collaborator. When his AddNew method is called, he forwards the newly
made model object to this parent's LaunchAddNew method. I can envision
this collaborator or parent having an interface and therefore more
testable by mocking the parent prior to the construction of the
presenter.
On the other hand, being able to pass a model object from the
presenter to the view and back (unscathed by the view, but modified by
a new presenter and its view,) solves a lot. In testing, I tell the
mock to ExpectAndReturn a call to the CreateAddForm method and return
a faked instance of my model object. In this method, I've kept my
concerns seperated, only passed higher order objects through a conduit
in the view to and from another presenter, yet still maintained
testability.
But the above solution can be tricky to implement. How are presenters
constructed? Do they need the current model layer? Does the model
layer need the handle to the persistence layer? So now the view is
bloated by a lot of non view-like things.
Are there better ways to handle this?
Ed
------------------------ Yahoo! Groups Sponsor --------------------~-->
Fair play? Video games influencing politics. Click and talk back!
http://us.click.yahoo.com/T8sf5C/tzNLAA/TtwFAA/nhFolB/TM
--------------------------------------------------------------------~->
To unsubscribe, email:
TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/TestFirstUserInterfaces/
<*> To unsubscribe from this group, send an email to:
TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/