Re: Adding a View to a Presenter

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Eric Taylor
Ian,

>However, I'm now a bit confused.  If you are implementing your class
"as
>OA implemented PushButton"...

I apologize.  I was referring strictly to the View side of the equation
and the fact that the instance of View was in the View itself, not a
Presenter.  I hadn't even looked to see if a PushButton has a
corresponding Presenter.

>If you are implementing your class "as OA implemented PushButton" then
you >won't need a Presenter;  the View subclass itself takes over the
role.

O.K., that tells me a lot (and I see, now, what Chris was talking
about).  But if you look at MoenTreeView, you'll see that it is a
subclass of View, but yet appears as a view instance in TreePresenter.
Is that because MoenTreeView itself has no instances of View?

I guess our confusion lies in the fact that we can't see a design
pattern to follow.  I understand what Andy was saying about instances of
existing Views versus entirely new Views.  That part is clear.  But I
guess the magic question is this: Why was MoenTreeView implemented the
way it was, and how does that design decision compare to the one
governing the implementation of PushButton?  In the former, we have a
special View with no instance of View, but rather itself becoming an
instance of View in a Presenter.  In the latter, we have a special View,
which _does_ contain an instance of View, but has no corresponding
Presenter associated with it.

Cheers,

Eric


> -----Original Message-----
> From: Ian Bartholomew [mailto:[hidden email]]
> Posted At: Thursday, June 08, 2006 9:33 AM
> Posted To: comp.lang.smalltalk.dolphin
> Conversation: Adding a View to a Presenter
> Subject: Re: Adding a View to a Presenter
>
> Eric,
>
> > I take it from the format of this statement that this is
specifically
> > for the case where one is adding a subclass of View to the
Presenter,
> > and not some instance of an existing view.
>
> Yes, sorry.  I've just re-read your question and realize that it's not
> quite
> what you were asking.
>
> However, I'm now a bit confused.  If you are implementing your class
"as
> OA
> implemented PushButton" then you won't need a Presenter;  the View
> subclass
> itself takes over the role.  Any view instance added to this class
will
> automatically become available in the ResourceBrowser.
>
> If you do want a Presenter then I don't _think_ you can do what you
want
> [1], although you _may_ be able to do it runtime by manually setting
the
> Presenter's view aspect.  Could get very messy though, however it's
not
> something I recall exploring - I've got few enough brain cells left as
it

> is.
>
> [1] Although I'm not completely sure what you want :-)
>
> --
> Ian
>
> Use the Reply-To address to contact me (limited validity).
> Mail sent to the From address is ignored.
>


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Ian Bartholomew-21
Eric,

> O.K., that tells me a lot (and I see, now, what Chris was talking
> about).  But if you look at MoenTreeView, you'll see that it is a
> subclass of View, but yet appears as a view instance in TreePresenter.
> Is that because MoenTreeView itself has no instances of View?

 From the D6 help page for Presenter (in the MVP section). ...

"While a view is responsible for the display of model information to the
user, a presenter's responsibility is to handle user input and use this to
manipulate the model data"

Some Views do not need any "user input", they have no model and the View
needs to handle any input all by itself .  In these cases (for example
PushButton, Splitter, GroupBox) there is no point in creating an extra
Presenter class as the View does it all for itself and therefore, to fit in
the MVP framework, it has to act as it's own Presenter.  You can see  which
classes behave in this way by "Inspecting"

(ResourceIdentifier allResourceIdentifiers
    select: [:each | each owningClass isKindOf: View class]
    thenCollect: [:each | each owningClass]) asSet

I can only assume that OA, as part of the original design of Dolphin,
decided there was no point in having dummy, do nothing, Presenters for these
classes and chose to give the View the ability to act as it's own Presenter.
I'm not sure if there is any other advantage to doing it this way, perhaps
Andy might like to comment?


I think, for consistency if nothing else, that it would be best to implement
a Presenter for every View subclass and associate the View instance with the
Presenter, using the code snippet I posted yesterday.

--
Ian

Use the Reply-To address to contact me (limited validity).
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Chris Uppal-3
In reply to this post by Eric Taylor
Eric,

[I don't know how much help this will be, like Ian I've re-read your earlier
question and seen that you weren't asking what I thought you were.  OTOH, your
latest post sounds as if you are still confused, so -- at the risk of repeating
stuff you already know -- I'll post this anyway.]

> O.K., that tells me a lot (and I see, now, what Chris was talking
> about).  But if you look at MoenTreeView, you'll see that it is a
> subclass of View, but yet appears as a view instance in TreePresenter.
> Is that because MoenTreeView itself has no instances of View?

It may help to focus a little on how this stuff works (I'll describe it in D5
terms because that avoids one or two potential confusions, then try to
back-patch the explanation to fit the D6 implementation).

As you know, at runtime you have an MVP triad consisting of an M, a V, and a P.
The question is, where does the V come from -- how does the system find it ?
The way it works is that there is what's known as a "view resource" which is
stored in a global registry keyed by both its string name (such as "Default
view", "Enhanced list view", etc) and /some/ class.  Normally that class is
Presenter or some subclass, occasionally it is a subclass of View.  The view
resource itself is just an instance of a View class saved down into a
serialised form (actually an STB-ed byte array[*]).  The important point here
is that there is no formal connection /at all/ between the View's class and the
Presenter class.  The only connection is that someone has chosen to create an
association in the registry between the Presenter class and that STB-ed View
instance.

If I created a new kind of numeric component -- say a rotary dial -- then I
would create a View subclass which implemented all the tedious graphics.
That's straightforward enough.  But then I have to /tell/ the system that my
new class is suitable for use as one possible view for a NumberPresenter.  I
may have designed my RotaryDialView perfectly to use the kind of numeric
ValueModel that a NumberPresenter does, but that's not enough.  I have to
create an instance of my new class, reduce it to a serialised byte array, and
shove it into the view registry under a name like "Rotary dial view" and
associated with NumberPresenter.  When, and /only/ when, I have done that, the
system will know that "Rotary dial view" is one of the view resources available
as a View for a NumberPresenter triad.

We do all that with the code snipped that Ian (and I) has shown you.

 From that time on the View Composer will "know" about the association, and also
you will be able to evaluate code like:

    model := 1.333 asValue.
    NumberPresenter show: "Rotary dial view" on: model.

which creates the NumberPresenter, finds the named view resource in the
registry, and copies that to create a new instance of RotaryDialView, and
finally binds the whole lot together into an MVP triad.

It may be worth mentioning explicitly that the Presenter class in a view
resource is /not/ used to create a Presenter.  /We/ create presenters (with
code like the above, or in our #createComponents methods).  The system creates
a complete (possibly deeply nested) View instance from the view resource, and
automatically links up the sub-presenters we have created with the
correspondingly named sub-views (that's to say the #name-s of the sub views as
seen in the VC).  If a sub-presenter has a name with no matching sub-view, then
it is just left unlinked (for flexibility).  If a sub-view isn't taken over by
one of the sub-presenters then it remains as it was when first created -- its
#presenter is itself.

Once we've created this first template instance (the initial view resource), we
don't need to do that again unless we want to recreate it from scratch.  Since
the VC now knows about that view resource, we can create variations on it in
the normal way -- just create a new, empty, view resource, drag/copy the
existing template into it, modify to taste, and save under a new name.
Similarly we can modify the initial template in-place in the VC and re-save.

Now, if I had devised a much more trivial view -- IrritatingFlashingLight,
say -- then there's no obvious Presenter class to link it to.  And, what's
more, there's no need for a special Presenter class (what would it do ?), so we
decide that these views shall be "self-presentered". But the /system/ doesn't
know that.  We still have to create a view resource exactly as before, but this
time instead of associating it with some Presenter class, we will associate it
with a View class (quite probably it's own class, as it happens, but that is
almost irrelevant).

In /this/ case you can, if you wish, create the new instance interactively with
the View=>new... menu option in the class browser.  (Although I remember you
saying you got walkbacks when you tried that in D6, and so did I when I tried
it, but today it seems to be working perfectly...)

Now, in D6 the logical picture hasn't changed at all.  There is still
(logically) a registry, containing named View instances associated with
Presenter (etc) classes.  The implementation details have change quite a lot,
though.  Now the "view resources" and their registry have vanished, to be
replaced by special methods on the class-side of Presenter (etc) classes.  The
View instances are no longer saved as STB-ed byte arrays, but in a different
format which is actually a complex array of Symbols, Numbers, and other stuff,
which forms the body of those special methods.

Oh, and there seem to be a few bugs in the system.  Although the beta period
for this new implementation went very smoothly, a few bugs have surfaced since
(unfortunately).

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Ian Bartholomew-21
Chris,

That's a _very_ good post, a clear explanation without delving into too much
detail.  Thanks for taking the time to put it together.

One to be placed in the WIKI when it returns.

--
Ian

Use the Reply-To address to contact me (limited validity).
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Chris Uppal-3
In reply to this post by Chris Uppal-3
Ian,

Thank you !

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Andy Bower-3
In reply to this post by Chris Uppal-3
Eric,

> That's a very good post, a clear explanation without delving into too
> much detail.  Thanks for taking the time to put it together.
>
> One to be placed in the WIKI when it returns.

I haven't got too much time to post in great detail (time to watch the
World Cup football!) but just a small idea to add to Chris' great post.

Try thinking of views in MVP as "Skins". Basically, a presenter
performs most of the grunt work of the UI but is able to be "skinned"
by one or more views. Does that help?

The "self-presentering"  that Chris has mentioned is largely irrelevant
these days. It is a hang over from the early days when we were
designing the framework (have you seen
http://www.object-arts.com/papers/TwistingTheTriad.PDF). At that point
we realised that MVP was going to be more complex than a typical widget
framework so we left in the ability to effectively support "widgets"
just in case we need to fall back on it for efficiency or simplicity's
sake. By a widget, I mean a visual component along the same lines as
those in Visual Basic or Java AWT. As it happens we eventually felt
that MVP was powerful enough to justify the extra complexity and so the
self-presentering really fell into disuse.

The only place where this in the case is in views that effectively
don't need any presenter. Ian (I think) has mentioned the case of push
buttons and container views which don't really need a model or a
presenter at all but for the sake of uniformity they are made self
presentering.

Maybe this helps a bit?

--
Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Andy Bower-3
Eric,

One more thing. I noticed that the link to the original Taligent MVP
paper (that was the inspiration for Dolphin's MVP) is broken in the
Twisting the Triad document. Here's another one:

http://www.hwswworld.com/downloads/9_15_05_z/mvp.pdf

Best regards

--
Andy Bower
Dolphin Support
www.object-arts.com


Reply | Threaded
Open this post in threaded view
|

Re: Adding a View to a Presenter

Eric Taylor
Chris, Ian, and Andy:

Thanks very much to all of you for your great replies!  I only just an
hour ago found the time to make a cup of tea, print out the replies, and
digest them all.  I also re-read "Twisting the Triad" and read (for the
first time) the Taligent paper on MVP.

Well, I believe I can now say that I've got it.  The idea of presenter
doesn't pose a problem for me, not at all.  Frameworks, in other
languages, that focus on n-tiered architecture all have something
similar, albeit not so elegantly named.  The problem lay in the idea of
view, or more to the point, the variations of the idea of view.

Chris, you point up "self-presentering" in what could be considered
trivial views; Ian, you see self-presentered views as (perhaps) OA's way
of avoiding dummy presenters; and Andy, you point out that they're sort
of a vestigial leftover from the early days of "widgets."  This,
precisely, was the sticking point for me, and it is a relief to know
that self-presentered views are no longer really a _mainstream_ design
pattern in Dolphin.  I say "relief" only because, as a rule instead of
an exception, they seem to be a bit of an oddball.

So, now we can feel free to create our presenters, either with just an
instance of an existing view or a whole new view behavior, and then
decide where to place the main logic of the triad: on the view side or
on the presenter side.  I already know from working with a couple of
n-tiered frameworks (outside the Eiffel domain and admittedly not in
great depth) that this decision is not always an easy one.

Again, thanks very much.  I think that now we're ready to proceed with
our command-bars ActiveX control design in the tradition of MVP.

Cheers,

Eric

 


Eric S. Taylor

> -----Original Message-----
> From: Andy Bower [mailto:[hidden email]]
> Posted At: Friday, June 09, 2006 11:56 AM
> Posted To: comp.lang.smalltalk.dolphin
> Conversation: Adding a View to a Presenter
> Subject: Re: Adding a View to a Presenter
>
> Eric,
>
> One more thing. I noticed that the link to the original Taligent MVP
> paper (that was the inspiration for Dolphin's MVP) is broken in the
> Twisting the Triad document. Here's another one:
>
> http://www.hwswworld.com/downloads/9_15_05_z/mvp.pdf
>
> Best regards
>
> --
> Andy Bower
> Dolphin Support
> www.object-arts.com