Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Build your own Cab – Answering some questions

 

First, go catch up on what’s come before:

  1. Preamble
  2. The Humble Dialog Box
  3. Supervising Controller
  4. Passive View
  5. Presentation Model
  6. View to Presenter Communication

I received some questions today that I thought were probably best addressed in a separate post.  If I’ve confused one person, it’s likely I’ve confused many.  Here we go…

 

First Question

“So does the presenter provide the data from the model to the view, or does the view also have a reference to the model?  Or does it depend on which of the patterns from earlier in the series that you pick?”

Short answer:  Yes, sometimes, and it depends.  

Long answer:  By and large I believe in the primacy of the Presenter, meaning that things start with the Presenter telling the View what to do rather than the other way around.  More specifically the Presenter “knows” about the Model first and then populates the View with the data in the Model.  Whether or not the Presenter fetches the Model, or is handed the Model, or creates the Model is a subject I’m going to put off until the posts on creating the ApplicationShell and screen coordination.  Back to the original question, how the View gets the data depends on the pattern used for the screen.

  • Autonomous View — There is no separate Presenter or Controller.  The View either creates the Model from scratch or gets the Model from another class
  • Supervising Controller — The Presenter/Controller is responsible for getting the Model first and setting up the View with all of the data it needs, including the Model.  With Supervising Controller we’re still content to let the View know how to display the various properties of the Model through data binding or another mechanism.  In this pattern the View definitely has a reference to the Model and is largely responsible for synchronizing screen state with the Model directly.
  • Passive View — In this case the View has no reference whatsoever to the Model.  The Presenter synchronizes the screen state with the Model (and vice versa) by explicitly mapping properties of the Model to public properties of the View which in turn set screen state.  What you’ll see in the View is a lot of getter and setter methods that delegate to screen elements like this:  get {return nameTextbox.Text;} and set {nameTextbox.Text = value;}.
  • Presentation Model — In this case the Presenter *is* the Model.  The View binds directly to the Presentation Model just like it would in the Supervising Controller

 

Second Question

“I’m still wrapping my head around the Presenter.  Is it tightly coupled to the view?  For instance if I have some code that says turn these fields blue when the user does x, does that code live in the presenter or the view?”

That’s a really good question because it skirts on some potentially treacherous ground.  How much should the Presenter know about the View?  How much should the View know about the Presenter?  Can I swap out the View?  If you read the scenario described above I’d say that you have two distinct responsibilities:

  1. Based on a certain user action, deciding that a visual indication should change on the screen (turning the fields blue)
  2. Making the visual indication on the screen

It’s very often advantageous to separate out the responsibility for deciding to take an action from the responsibility of carrying out the action.  You’ll see this time and time again in Object Oriented Programming, especially if you employ Test Driven Development.  Turning the fields blue is definitely a View responsibility to me.  This code in the Presenter _view.ColorOfFooField = ‘blue’ feels very wrong to me.  I’d rather the Presenter do this:  _view.IndicateFooIsSomeCondition().  The Presenter is supposed to be about behavior, and the second choice is much more semantically meaningful to me in terms of behavior.  The View is responsible for presentation and should get to decide how some sort of screen indication is made.

To summarize I guess I’d say that the Presenter really shouldn’t know the intimate details of the presentation, including color.  I think calls to EnableFoo() or DisableFoo() are generally correct because that is screen behavior that’s generally determined by business rules and screen logic.  Ideally the Presenter should not be so tightly coupled to the View that you could not swap in a completely different View class (going from WinForms to WebForms may be too much to ask though).

Just to confuse the matter, I use the term “Embedded Controller” to refer to “user interface widget-aware” classes that can help a View do some of the presentation work.  For example, if I decide I want to make some sort of common screen indication (like turning a field that has invalid data or changed data blue) a common way across the system I might create an Embedded Controller that’s reused across screens.  I call it an Embedded Controller because it’s completely contained within a View as just a part of the View’s machinery.  The most immediate example I can recall is a “GridHelper” class to help bootstrap the standard “sort, page, query, filter” functionality that’s similar across screens.

 

My Question

“How does Acropolis effect this?”

I have no idea yet, but I’ve heard it’s supposed to be pretty cool.  I would have an idea, but I missed the Acropolis session at the MVP Summit because Bellware sent me on a wild goose chase to the wrong building.

 

 

Clear as mud?  You know, as many topics have come up from this series, I think this would be a good idea for a book…              …written by someone else.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Build your own CAB, Design Patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Diamond

    In confused on how the passive view pass data from the view to the presenter to the model without the view referencing the model. Can you please explain the flow of the data.

  • http://icoder.wordpress.com Alex McMahon

    @Borris,
    Wouldn’t it be the following:
    Form 1 communicates with Presenter 1 (either event based or directly) saying the button was pressed
    Presenter 1 creates an instance of Presenter 2 passing in the IView2 for it to use*
    Presenter 2 creates View 2

    * – This is the tricky part I think, as you don’t want presenter 1 having a direct dependency on presenter 2, I guess this might be where the application controller comes in, or a proper IoC framework

  • Borris

    I have found all these discussions very helpful as I’m in the process of designing a UI framework for an existing large winforms app, currently written with very little or no structure.

    However, all example code I’ve seen so far on MVP only has one form. So the relationships is 1 form implements 1 view which is used by 1 presenter.

    Say we have 2, Form1 & Form2 implementing Interface1 and Interface2 respectively.

    Form2 gets opened from Form1 by the user clicking a button which raises an OpenForm2 event in Interface1. What is the best way to handle this event? The presenter can’t create a new form as it’s unaware of the views implementation (could be the web). Could use a factory class in the presenter which complicates things. My approach would be to handle the event directly in Form1. So Form1 button click handler in Form1 creates a new instance of Form2 and shows it. Form2 then creates its own presenter classes it requires and so forth.

    I appreciate any comments.
    Cheers.

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    Joseph,

    Short answer: Lots of different ways.

    Long answer: If you’re going to need to do this, you keep the original state around in one form or another and reapply the original state. If it’s a DataSet you can just reject the changes. If it’s a custom object for the model, you might Clone it and keep the original state first for this very reason. You might even just go fetch the data from the backend.

  • Joseph Gutierrez

    2nd Question: How would you handle an undo for a text box?

  • http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

    Are you kidding? I feel lucky they didn’t sick security on us when we showed up at the wrong building. I kept looking for one of those little wheeled robots that the Stormtroopers used to get around the Death Star.

  • http://www.bellware.net ScottBellware

    Actually, the goose was domesticated. It’s this misinterpretation on your part that I believe was the cause of your having missed the session on Acropolis. And frankly, I’m shocked at your insinuation that there could be a “wrong” building at the MS campus :)

  • Max

    As long as the book was liberally laced with the travails of Porthos, Athos and Aramis, it sounds like a winner :-). I miss those guys..