Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MVP pattern - presenter pulling data from the view interface vs. view implementationS pushing data into the presenter ?

28 views
Skip to first unread message

Tomas Johansson

unread,
May 21, 2009, 6:02:04 PM5/21/09
to
This thread is about the Model-View-Presenter pattern, and more
specifically about the presentation of the MVP pattern in the book
"Agile Principles, Patterns, and Practices in C#" (by Robert C. Martin
and Micah Martin, below reffered to as 2x Martin's).

My interpretation of how the MVP pattern is supposed to be implemented
is different from the code example in that book.
I do not necessarirly claim that the 2x Martin's pattern is incorrect
(but I believe so) since I have not seen any code example (and thus
can not compare) from the original creator of the pattern who "owns"
it (so to speak).
However, I would like to hear if my opinion (as explained below) is
shared with most guru's in this group, or if you would say that the
book authors indeed have implemented MVP in an appropriate way.

Actually, I think that my question can be separated into two
questions:

Question 1:
Is it correct to consider the pattern in the book as a variant of the
MVP pattern, or is it too different from the original pattern
description and/or too different from other descriptions of the
pattern (such as the below mentioned MSDN article or Martin Fowlers
patterns) ?

Question 2:
Regardless of what names we choose to use for these two pattern
variants, is it better (and if so, why?) to push data from the view
implementations into the presenter, rather than pulling view data from
the presenter through a view interface ?

My current answer to both these questions are no.

Firstly, (regarding question 1 above) I believe the answer is no,
because my general impression (based on code examples and books/
articles that I have read) is that it seems more common to pull data
from the presenter through a view interface rather than defining
properties on the presenter that all view implementations will have to
set.

Secondly, (regarding question 2 above) it seems better to really have
as little code as possible in the view classes, and avoid all the
presentation logic there (and in fact that is also what the authors
themselves write at page 639).
For example, as illustrated in the code snippet (from the book) below
with a Windows Forms view, the same kind of presentation logic would
become duplicated in an ASP.NET implementation, in the method that
disables/enables two text boxes depending on the value of a clicked
radio button.
As I try to illustrate further down in this posting, I think it would
be better to implement that kind of presentation logic in a presenter
object.
If you do define (as I prefer) a view interface with all data that
needs to be retrieved, then it will also be very easy to create
another view implementation, since the compiler will help you by
telling which methods that needs to be implemented.
On the other hand, if you would create another implementation with
code like in the mentioned book, then you will have to know more about
what to do (without being able to get that help from the compiler and
IDE to generate method skeletons that can be trivially implemented),
for example in an ASP.NET implementation you will have to (in a method
corresponding to the below "commissionRadioButton_CheckedChanged")
implement it in the same way, by enabling/disabling two text boxes,
and also setting a property of the presenter object.

My preferred interpretation of how to use the Model View Presenter
pattern is more like the code example in the MSDN article
http://msdn.microsoft.com/en-us/magazine/cc188690.aspx

There is a fundemental difference in these two code samples, which
both claims to be using the MVP pattern (even though IMHO they are
quite different):
(1) The mentioned book (by 2x Martin) lets the view implementation be
responsible for pushing view data into properties of the presenter
object
(2) The MSDN article lets the presenter pull input through a
generically defined view interface

Here is a code snippet from (1) illustrating that the view pushes view
data into the presenter object, by setting presenter property values,
from the event handling methods in the view implementation:
http://www.codeproject.com/KB/books/PatternsPractices.aspx
public class AddEmployeeWindow : Form, AddEmployeeView
{
private AddEmployeePresenter presenter;
...
private void commissionRadioButton_CheckedChanged(object
sender, System.EventArgs e)
{
commissionSalaryTextBox.Enabled =
commissionRadioButton.Checked; // presentation logic !
commissionTextBox.Enabled =
commissionRadioButton.Checked; // presentation logic !
presenter.IsCommission = commissionRadioButton.Checked; //
pushing data to a presenter property !
}
private void empIdTextBox_TextChanged(object sender,
System.EventArgs e)
{
presenter.EmpId = AsInt(empIdTextBox.Text); // pushing
data to a presenter property !
}

...

The above code snippet does not only illustrate that view information
is pushed into the presenter (which another implementation also would
have to do) but also that the view implementation has presentation
logic that needs to be duplicated in another view implementation, i.e.
if you want to use ASP.NET as a user interface, then a similar ASP.NET
implementation method would also enable/disable two text boxes (plus
setting the property of the presenter object).


Here is some (simplified) code snippets from (2), illustrating that
the presenter pulls information from the view interface:
http://msdn.microsoft.com/en-us/magazine/dd279548.aspx?code=true&level=root%2csrc%2capp%2cMVP.Presentation&file=ViewCustomerPresenter.cs
http://msdn.microsoft.com/en-us/magazine/dd279548.aspx?code=true&level=root%2csrc%2capp%2cMVP.Presentation&file=IViewCustomerView.cs
public interface IViewCustomerView
{
ILookupList CustomerList{get;}
...
}
public class ViewCustomerPresenter
{
private readonly IViewCustomerView view;
...
public void DisplayCustomerDetails()
{
// here the presenter pulls from the view interface, with
'view.CustomerList':
CustomerDTO customer = task.GetDetailsForCustomer
(view.CustomerList.SelectedItem.Value);
...

As I mentioned, the above code is a bit simplified to make it easier
to read and understand the important difference (i.e. that the
presenter pulls from the view) and as you can see in the real
implementation if you click the above link, the MSDN code was using a
helper method and using an if statement and some integer parsing, but
those things are not very significant for this discussion, so
therefore I removed them. ( But actually, one interesting detail with
the code that I simplified/removed from the MSDN code, is that the
integer conversion was done in the presenter, while the 2x Martin book
converted an integer from the view implementation. I have removed that
integer conversion in my changed implementation further down. )


As a comparison, if the above MSDN code snippet would have been using
the same kind of pattern as in the 2x Martin's book, then I think it
would have looked more like something like this:
public class ViewCustomerPresenter
{
public string CustomerID { get; set; }
public void DisplayCustomerDetails()
{
CustomerDTO customer = task.GetDetailsForCustomer(this.CustomerId);
}
and then of course it would have been necessary for the view
implementationS to set the property "viewCustomerPresenter.CustomerID"
before the method "viewCustomerPresenter.DisplayCustomerDetails()"
would become invoked.

According to my preferred interpretation of the MVP pattern (as in the
MSDN example), the so called MVP code in the 2x Martin's book (the
code snippet I used further above in this posting) would rather have
been implemented in a way that looks as in the code below:

// Define an interface with the input, to be retrieved from the
Presenter:
public inteface AddEmployeeView {
bool isCommissionEmployeeSelected();
void EnableCommissionSalary(bool enabled);
void EnableCommission(bool enabled);
string GetCommissionSalary();
string getEmployeeId();
...
}

// Implement the View, with a trivial implementation of the above
defined view interface, without the original (as in the book)
presentation logic:
public class AddEmployeeWindow : Form, AddEmployeeView {
private AddEmployeePresenter presenter;
...
public bool isCommissionEmployeeSelected() {
return commissionRadioButton.Checked;
}
public void EnableCommissionSalary(bool enabled) {
commissionSalaryTextBox.Enabled = enabled;
}
public void EnableCommission(bool enabled) {
commissionTextBox.Enabled = enabled;
}
public string getEmployeeId() {
return empIdTextBox.Text;
}

private void commissionRadioButton_CheckedChanged(object
sender, System.EventArgs e)
{
// Here is a significant difference compared with the book, i.e. I
have no presentation logic here, and
// no setting of data propertes in the presenter, but only a trivial
invocation
// of a method in the presenter, and that presenter will then call
back
// to a generic view interface to retrieve the data, and apply the
presentation logic,
// for example which other view elements that should be enabled/
disabled
presenter.CommissionSelectionChanged();
}
(
Please also note that the 'employeeId' is above intentionally returned
as a String and not converted to an int (as in the original code
snippet invoking an "AsInt" method), since that conversion should
otherwise have to become duplicated in another view implementation.
Instead, I think the presenter should do that conversion once, rather
than doing it once for each view, and really keeping as little code as
possible in the view implementations.
(just like the 2x Martin authors themselves write in the book, quote
from page 639: "...we'll write as little code in the Windows Forms as
possible...")
)

// Implement the Presenter, by pulling the data from the generic view
interface (rather than having it pushed from view implementationS)
public class AddEmployeePresenter {
private AddEmployeeView view;
...

// Note that I removed the following property that previously (as in
the book code) was supposed to be set from the vew implementationS
// and instead lets the Presenter pull the information from the
generic view interface method 'isCommissionEmployeeSelected()'
// public bool IsCommission { ... }

public void CommissionSelectionChanged() {
// Now I implement the presentation logic here ONCE, instead of
having this kind of logic
// duplicated in different view implementations (e.g. Windows Forms
and ASP.NET implementations)
bool isCommissionEmployeeSelected = view.isCommissionEmployeeSelected
();
view.EnableCommissionSalary(isCommissionEmployeeSelected);
view.EnableCommission(isCommissionEmployeeSelected);
}

As you may know, Martin Fowler has renamed/splitted the MVP into two
patterns, and I really think that *at least* one of them (the "Passive
GUI") should definitely be consistent with my interpretation of the
MVP (i.e. pulling from the presenter through the view interface) since
the Passive GUI is his MVP variant that really should have as little
code as possible in the View implementations.
However, I think that the other variant (i.e. the "Supervising
Controller") also seems to be described as that the presenter should
still pull information from the view.
There is no source code in these pattern descriptions by Fowler, but
the Sequence diagram in figure 2 for the Supervising Controller has an
Assessment Controller (i.e. the "Presenter") that pulls data from the
Text Field (i.e. the "View") by invoking the method "getText".
( some links to these Fowler's pattern descriptions:
http://www.martinfowler.com/eaaDev/SupervisingPresenter.html
http://www.martinfowler.com/eaaDev/PassiveScreen.html
http://www.martinfowler.com/eaaDev/ModelViewPresenter.html
)
Therefore, I do not believe that the 2x Martin's (Robert and Micah)
MVP is a variant of Fowler's Supervising Controller, since the way I
see it both Fowler's variants should let the Presenter pull
information from the view interface, rather than letting the view
implementations push information into the presenter.

Finally, I would just like to mention that I am indeed aware of the
fact that one of the authors of the book, Robert C. Martin (a.k.a.
Uncle Bob) is a quite famous authority within the software industry,
and it just seems strange to me that he would have misunderstood the
MVP concept and published an "incorrect" MVP implementation...
In the section "Acknowledgments" in the book, there are also some
other famous names there, actually including Martin Fowler himself
(which IMHO has published a different kind of MVP...) but also Kent
Beck, Ron Jeffries and Grady Booch.
I assume that at least some of these mentioned people did read an
early manuscript draft of the book before it became published, but
nobody seems to have given Uncle Bob feedback that convinced him that
in the MVP pattern, the presenter should pull information from the
view rather than letting the view implementationS push information
into the presenter.

So, maybe it is me who has misunderstood something, or what do you
people here have to say about the two questions in the top of my
posting above ?

/ Tomas Johansson

H. S. Lahman

unread,
May 22, 2009, 11:10:07 AM5/22/09
to
Responding to Johansson...

> Question 1:
> Is it correct to consider the pattern in the book as a variant of the
> MVP pattern, or is it too different from the original pattern
> description and/or too different from other descriptions of the
> pattern (such as the below mentioned MSDN article or Martin Fowlers
> patterns) ?

MVP is Microsoft's name for the MVC infrastructure originally developed
for some Smalltalk environments. IMO calling it a pattern is a pretty
loose way to use 'pattern' since it is actually an infrastructure to
support a model of application execution.

That aside, I think the answer is Yes. MS' implementation of MVP
probably has millions of LOC behind it. IOW, is is BIG to support
arbitrarily complicated pipeline applications between the DB and UI.

I believe Martin's goal is to provide a usable pattern for doing
essentially the same thing on a much smaller scale. IOW, no one in their
right mind would implement an entire BASIC interpreter using the GoF
Command pattern but there are lot's of contexts with a few limited
commands where the Command pattern would be quite useful compared to
providing an entire BNF parsing capability. I think Martin's goal is
similar: provide a UI/DB pipeline pattern for small applications that
have limited display complexity without dealing with a lot of
infrastructure.

>
> Question 2:
> Regardless of what names we choose to use for these two pattern
> variants, is it better (and if so, why?) to push data from the view
> implementations into the presenter, rather than pulling view data from
> the presenter through a view interface ?

The answer is a definite Maybe. If the dominant direction of flow in the
pipeline is from DB to display (data access), then pulling will probably
be easier to implement. If the flow is from display to DB (data entry),
then pushing will probably be easier.

Having said that, I think push/pull is irrelevant. If one is thinking
about MVP as a design pattern, then push/pull is a pure implementation
issue. IOW, you can implement the pattern unambiguously either way
without change.

<aside>
Martin and I have been going around about his code-centric view for
decades. B-) I think this is a good example of how being code-centric
can obscure design issues. To demonstrate the pattern in his book with
code Martin had to choose a particular OOP implementation strategy. Thus
the fact that push/pull *is* an OOP implementation strategy that has
nothing to do with the OOA/D of the pattern gets lost and one starts
worrying about it as a *design* issue.
</aside>

--
Life is the only flaw in an otherwise perfect nonexistence
-- Schopenhauer

H. S. Lahman
H.la...@verizon.net
software blog: http://pathfinderpeople.blogs.com/hslahman/index.html

use...@oo-systemutvecklare.se

unread,
May 23, 2009, 9:36:44 AM5/23/09
to
On May 22, 5:10 pm, "H. S. Lahman" <h.lah...@verizon.net> wrote:

> MVP is Microsoft's name for the MVC infrastructure originally developed
> for some Smalltalk environments.

The current MVP article at wikipedia
http://en.wikipedia.org/wiki/Model-view-presenter
has a link to a PDF article from 1996 written by Taligent (subsidiary
of IBM) about Model-View-Presenter.
Therefore, I am not convinced that it is correct to say that MVP is
Microsoft's name.

> IMO calling it a pattern is a pretty loose way to use 'pattern' since it is actually
> an infrastructure to support a model of application execution.

Here is a common definition of what a pattern is: "a named description
of a general, reusable and proven solution to a recurring problem in a
context".
An example of a recurring problem description (phrased as a question)
in a GUI development context could be written like this:
"How can we separate the view implementations from the presentation
logic, in such a way that it will be easy to implement regression
testing suites for the presentation logic, while also making it as
easy as possible to replace one view with another, and/or to
supporting multiple views with as little duplication as possible ?"
The above sentence may not be the perfect phrasing of the problem that
MVP is a potential solution for, but I think it at least illustrates
that it is reasonable to consider MVP as a pattern.
The authors in the mentioned Taligent article write that: "we believe
the MVP programming model is a fundamental design pattern for
applications development.", but I think it more can be seen as an
architectural pattern, just like the MVC pattern is classified in the
"POSA" book (Pattern-Oriented Software Architecture, volume 1).


> ... Having said that, I think push/pull is irrelevant. If one is thinking


> about MVP as a design pattern, then push/pull is a pure implementation
> issue. IOW, you can implement the pattern unambiguously either way

> without change....


> the fact that push/pull *is* an OOP implementation strategy that has
> nothing to do with the OOA/D of the pattern gets lost and one starts
> worrying about it as a *design* issue.

Now I do not quite understand what kind of definitions you are using
when you are talking about "design" and "implementation strategy".
IMHO, a common definition for what *design* is about, is the kind of
definition that Craig Larman is using (quote from page 7 in his book
"Applying UML and Patterns", 3rd edition):
"defining software objects and how they collaborate to fulfill the
requirements".
In the POSA book's definitions about architectural patterns and design
patterns, they describe them as guidelines/scheme for organizing/
refining relationships between the components in a software system.
I think the relevant phrases (for this discussion) are "how they
collaborate" and "guidelines for organizing relationships".

Regarding the current *design* discussion of MVP, I think it is an
essential design/architectural guideline to define whether or not the
Presenter should invoke getter methods defined in a view interface, or
whether the view implementations instead should invoke "setters"
defined in the Presenter classes. Without such guideline (i.e. if you
would just say that the View/Presenter collaboration is an
implementation detail) then you will unlikely end up with a consistent
architecture, but some developers (working within the same
application) might choose to implement Presenters with pulling from
the view interface getters, while other developers would let their
view implementations push GUI input into setters of the Presenters.

Regarding the meaning of the phrase *implementation strategy*, I do
not think that a modification of the collaborations through public
methods can be seen as implementation strategies.
IMHO (but I might be wrong?) the word *implementation* implies that we
are talking about privately encapsulated details.
As an example of what I consider to be an implementation strategy: If
we would be implementing some parameterized factory method, one
*implementation strategy* could be to use a bunch of if/else/switch
statements to choose a concrete object to instantiate and return.
Another *implementation strategy* would be to let the factory class
define a private hashtable where prototype objects are being stored,
and then the factory method could be trivially implemented by
retrieving a prototypical object from the hashtable and returning the
result from its clone method.
If we would switch one such implementation strategy (according of what
I am reading into that phrase) with another, then it will not affect
the client code, i.e. users of the public API will be unaffected and
thus it can be seen as an *implementation strategy* (IMHO).
On the other hand, regarding the collaboration between objects, i.e.
whether the Presenter should invoke getter methods of the view, or if
view implementations should inoke setter methods of the Presenter,
that kind of difference is not an implementation detail but a *design*
decision affecting the public method signatures.

This is how I think about the concept of an *implementation strategy*
vs. what *design* means, and I do not understand the reasoning about
why the collaborations should be thought of as an implementation
strategy.

BTW, please also remember that one of the reasons for defining
patterns is to simplify communication.
If we are too flexible about how the collaboration should be done
within a pattern (compared to some defined collaborations in text and/
or a sequence/interaction diagram in the pattern definition) then the
semantic of the pattern is starting to get lost, i.e. it does not
really mean much to say that we are using a particular pattern if we
just say that deviations of the collaborations are "implementation
details".

/ Tomas Johansson

H. S. Lahman

unread,
May 23, 2009, 10:24:27 AM5/23/09
to
Responding to usenet...

>> IMO calling it a pattern is a pretty loose way to use 'pattern' since it is actually
>> an infrastructure to support a model of application execution.
>
> Here is a common definition of what a pattern is: "a named description
> of a general, reusable and proven solution to a recurring problem in a
> context".

My point was that "MVP" is typically associated with MS' particular
infrastructure rather than the underlying pipeline layered model shared
with other infrastructures like MVC. IOW, there is only one MVP
implementation for layered model infrastructures so it isn't a pattern
for layered model infrastructures.

>> ... Having said that, I think push/pull is irrelevant. If one is thinking
>> about MVP as a design pattern, then push/pull is a pure implementation
>> issue. IOW, you can implement the pattern unambiguously either way
>> without change....
>> the fact that push/pull *is* an OOP implementation strategy that has
>> nothing to do with the OOA/D of the pattern gets lost and one starts
>> worrying about it as a *design* issue.
>
> Now I do not quite understand what kind of definitions you are using
> when you are talking about "design" and "implementation strategy".

In the OO paradigm there are three levels of application design: OOA,
the resolution of customer functional requirements independently of
computing environment; OOD, the strategic resolution of functional and
nonfunctional requirements for a particular computing environment; and
OOP, the tactical resolution of requirements for particular technologies
(3GLs, interoperability infrastructures, etc.). [In MDA terms OOA maps
to a PIM, while OOD and OOP map to PSMs at different levels of abstraction.]

Design patterns, such as the DB/UI layered pipeline models (which is the
basis for the MVP infrastructure) and the GoF patterns, are defined at
the OOA/D level. At that level of design the tactical implementation of
push vs. pull techniques is not specified because that depends, at least
to some extent, on the vagaries of the particular implementation
language and the infrastructures used. IOW, push vs. pull is a tactical
design issue for OOP.

Note that the GoF are careful to have a special section that isolates an
implementation to provide an *example* mapping of the pattern at the 3GL
level. In doing so they needed to pick particular tactics for the
examples. But one is free to tactically implement the pattern in other
ways during OOP.

In fact, apropos of the first point, I would argue that another reason
regarding MVP as a pattern is a stretch is because it *does* make the
push/pull decision -- which was exactly what the OP was concerned about
because Martin chose the opposite tactic for implementing the UI/DB
pipeline. IOW, the difference existed because they were different
concrete OOP implementations of the same OOA/D design pattern.

0 new messages