First, go catch up on what's come before:
- Preamble
- The Humble Dialog Box
- Supervising Controller
- Passive View
- Presentation Model
- 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:
- Based on a certain user action, deciding that a visual indication should change on the screen (turning the fields blue)
- 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.