Presenter First: Transient Triads
I recently got an email asking when and where to instantiate MVP triads (and supporting objects) that appear in response to events in the system, but are not to be built at application start time. MDI (multiple document interface) applications are a good illustration of this: when your application starts, you have zero document editors, but as the user opens documents, you will have several editors. Who builds these transient triads?
The Question:
Hi,
... I am writing and application that consists of a Navigation pane which is a TreeView and a pane to display what has been clicked on in the navigator in tab form using a TabControl. I currently have the following triads
NavigatorModel, NavigatorPresenter, NavigatorView TabViewerModel, TabViewerPresenter, TabViewerView Type1Model, Type1Presenter, Type1View Type2Model, Type2Presenter, Type2View
Type1 & Type2 are different types of content that are to be displayed in the TabViewer. I am a bit confused now on where the Type1 & Type2 triads should be instantiated.
... Thanks for your time
Gavin
The Response:
Hi Gavin,
I would probably have a Factory object of some kind composed into the TabViewerModel. It could take some symbolic indicator of which type of thing you need to instantiate and view (Type1 or Type2), and perhaps the fundamental data needed to configure the newly created triad. The Factory then instantiates the requisite model, view, presenter (and any other supporting objects you may need in that little cluster)... then return a tuple containing a reference to both the new Model and View instance.
You need the View instance, obviously, because you’ve got to plug it into the tab view pane, or whatever. You might transfer this from the TabViewerModel through the TabViewerPresenter.
We’ve often needed to retain a reference to the Model in order to communicate with this newly created arm of the application… your needs or design may work differently. In this scenario, the new Model would wither be kept directly by the TabViewerModel, or TabViewerModel might pass it off to some sort of collection manager elsewhere in your system.
We tend to use dependency injection systems like Spring and Spring.NET (DIY for Ruby) to describe our object systems. For the overall system, we have a “main context” that would, in your case, describe the composition of Navigator* and TabViewer*, and also the TypeFactory instance.
Then, we create “sub contexts” to describe Type1 and Type2 MVP triads. The TypeFactory object would use the Spring library to load up a sub context from an XML file dedicated to, say, the Type1 triad.
The Factory approach is probably a better approach than burdening your presenters with the chore of multi-object instantiation and composition. (An alternate approach might be: compose the Factory object into the Presenter…)
One parting tip: Object instantiation, though very small in code, is a serious responsibility for an object to undertake, so don’t feel bad about spending a little extra time and effort to do it right.
Hope this helps! /Dave
Leave a Reply