[Seaside] MVP on Seaside

Sebastian Sastre ssastre at seaswork.com.ar
Thu Sep 2 21:39:57 CEST 2004


I answer below,

Sebastián Sastre
ssastre at seaswork.com.ar
www.seaswork.com.ar


> -----Mensaje original-----
> De: seaside-bounces at lists.squeakfoundation.org
> [mailto:seaside-bounces at lists.squeakfoundation.org] En nombre 
> de Avi Bryant
> Enviado el: Martes, 31 de Agosto de 2004 08:35
> Para: The Squeak Enterprise Aubergines Server - general discussion.
> Asunto: Re: [Seaside] MVP on Seaside
> 
> 
> 
> On Aug 31, 2004, at 2:25 AM, Sebastian Sastre wrote:
> 
> >> I've spent a lot of time thinking about how this might work and
> >> building small experiments, but I've never come up with 
> anything I'm
> >> even remotely satisfied with.
> > In those experiments do you ever tried this well proven framework 
> > (MVP)?
> 
> I've never really used Dolphin, so I only know about MVP in theory,
> from reading the "twisting the triad" paper and so on.  I've 
> certainly 
> experimented with ideas from MVP, but it's not clear in my head what 
> just "using" MVP directly would mean in a Seaside context.  

The association came to me because I use dolphin daily taking advantagge
of this framework AND because you called the WAPresenter class in that
way :)

> If there's 
> an obvious design you have in mind, I would definitely 
> encourage you to 
> implement it, at least to a proof-of-concept level, so that 
> we can all 
> better understand MVP and how it would apply here.

I'll try to do my best, I think I could start making WebView and
WebPresenter so then I can make the WebCanvas and WebShell subclasses
respectively. Perhaps the ListPresentersPresenter (see below).

> >  I also see that (in desktop developments) allways
> > one have to deal, intensively, with model and presenters, rarely on
> > views. I'm trying to get this benefit to the web applicatoin 
> > development, so we can get the energy only in model and application 
> > models (or presenters), and rarely on views.
> 
> This is what I'm disputing.  The aesthetic of the web is such that
> inevitably, any application that you write is going to have a large 
> number of custom views.
I understand your point but I also think that that inevitability could
not imply a view classes proliferation. In other words, web views can
also be factorized. In this case we have to figure out, how we can
factorize well enough the WebView hierarchy to have detailed basic
views, so it can be "customized" in innumerable ways. This large number
of customized views will be stored in the presenter and that don't
implies to have that (the same) large number of view subclasses. May be
one or two with a diferent specialized behavior like this example:
BasicListAbstract class has 2 subclasses: ComboBox and ListBox, and
ListBox has MultipleSelectionListBox subclass.
This classes should keep all the knowledge about drawing a list (using
the renderer) in every possible way for them, and to reflect the changes
of it's model.

  It is also, hopefully, going to have a 
> reasonable number of standard views (or the reusability claims for 
> Seaside components would be much less interesting).  But take 
> something 
> like Google - how much of what you see would be included in a 
> standard 
> view library?  The text input and Search button, yes.  But the search 
> results?  All the custom links that pop up (translate this page, 
> cached, similar pages)?  The Goooogle pagination?  The AdWords on the 
> side?
I see them all as presenters. Presenters could be composed one into each
other, so I'll make an hipotesis of how all this could be made ok?

Pagination of results: 

The BatchSelectionPresenter is a presenter, the BatchSelectionFooter is
another

BatchSelectionFooterPresenter
0. It's model is the collection, so it can calculate the ammount of
pages.
1. Some static texts, and anchors.
2. has images presenters (of each letter of Goooooogle) with it's links.
3. the right blue arrow is an static image that triggers an event when
it's clicked, because it was configured to do so. The
BatchSelectionFooterPresenter hooked this event so it can
trigger:#nextPageRequested
4. The number of result pages is it's made with anchors that when
clicked simply trigger:#pageRequested: with: pageNumber.
5. When changing the page, this presenter draws the left image and link
as it needs.
6. It also remember the current page. 

BatchSelectionPresenter
1. The BatchSelection presenter, when instantiated, adds a subpresenter:
a BatchSelectionFooterPresenter, hooks it's interest in some events:
#nextPage, #previousPage, #pageRequested:
2. Implements the methods onPageRequested:, onNextPage, onPreviousPage, 
3. It has as model the collection of results so it can pass this items
as model of a ListPresentersPresenter 
4. This ListPresentersPresenter, knows how to draw presenters one below
each other, and ties the events of this instanciated presenter so it can
re-trigger them saying who was the originator (aResult).
5. So this presenter instanciates the 4, 8 (or whatever the batch say)
ResultPresenter one below eah other. This specialized presenter already
know what to do when are clicked (somethig concrete or just trigger that
that happens).

Perhaps the a code example could tell you in some other way. The
GoogleBatchSelectionPresenter inicialization could look like this:

GoogleBatchSelectionPresenter>>createComponents
	footerPresenter := self add: BatchSelectionFooterPresenter new
name:'footer'.
	listPresenter := self add: ListPresentersPresenter new
name:'results'.
	listPresenter 
		whenPresenters:#translateRequired:
send:#onTranslateResult: to:self;
		whenPresenters:#cacheRequired: send:#onCachedRequired:
to:self;
		whenPresenters:#similarRequired:
send:#onSimilarPagesRequired: to:self.

"I'm thinking how to solve the EventRouter needed to implement the
routing of hooked events to implement the method #whenPresenters... but
we'll see."

GoogleBatchSelectionPresenter>>createSchematicWiring
	super createSchematicWiring.
	footerPresenter 
		when:#nextPage send:#onNetxPageRequired to: self;
		when:#previousPage send:#onPreviousPageRequired to:
self;
		when:#pageRequested: send:#onPageRequested: to: self.

GoogleBatchSelectionPresenter>>onNetxPageRequired
	listPresenter model: self nextPage.

Publicity in the results page: 
A vertical shaped shell (presenter) that has a GoogleAddPresenter, etc
 
> If you accept that a web application requires proportionally more
> custom views than a desktop application does, then the tradeoffs 
> change.  There is almost certainly more total effort involved in 
> writing a separable View/Presenter pair than in writing them 
> in a more 
> tightly coupled way.
>  In standard desktop MVP, that effort is 
> worthwhile because the work to create the View is amortized over many 
> Presenters.  If, as in the web, you are often writing a new View that 
> will only be used by a single Presenter, that effort may no longer be 
> worth it.
Perhaps, but at the price of loosing flexibility and extensibility.
Every time you want to do somethig, you'll have to deal with html forms
and tables. I dont like to deal with html tables, tags, etc. Maybe it
just a price too high for some developers.

> 
> I say "may" because it's possible/likely that I just haven't
> found the 
> right way to make View/Presenter pairs easy enough to write, or the 
> right way to structure my code so that individual views (given the 
> right CSS, say) can be used in a wider range of apps.  That's 
> definitely a direction I'd like to move in, and I'm far from 
> giving up. 
That's very good! :)

>   But I do think it's a mistake to assume that just because a 
> paradigm 
> has been proven in the desktop arena, it is necessarily a good design 
> for web apps.
Well, in one hand, until we see it very clear why not, we can assume
that the paradigm is valid, and in the other hand, I think is desirable
to heredates a mature framework to this new domain. All that I'm
proposing here is that if we can make the domain transformations well
enough, we can make this heritage to pass from the desktop to the web. 

> > As you'll see all arround in many frameworks in smalltalk, more
> > classes does not implies more complexity, when it's well designed, 
> > more classes implies simplification (of the ideas), specialization, 
> > decoupling and flexibility. So I don't see that as a barrier.
> 
> It's not so much the proliferation of classes that concerns me as the
> necessary decoupling.  Seaside relies heavily on lexical 
> scope as a way 
> to connect views to models. This can simplify things immensely, but 
> the only way I've managed to get it to work is by 
> constructing views on 
> the fly (if you consider what HtmlRenderer is doing to be 
> "constructing 
> views")
Yes I think a renderer is a great specialized tool. It's our pen to the
html. Our benefactor from the html jungle.

>, and so there's necessarily code to do this in the 
> presenter/component.  This is coupling, but it's coupling 
> that allows a 
> valuable concision that I really don't think would be possible 
> otherwise.  Let me give you an example: let's say have a 
> collection of 
> Person objects that I want to show in an unordered list, where each 
> list item includes the person's name, a text input for editing some 
> part of their address, and (if the person is removable) a link for 
> deleting that person from the list.  In Seaside's current, "coupled" 
> style, this might look like:
> 
> html list: persons do:
> 	[:ea |
> 	html text: ea name.
> 	html textInputOn: #street of: ea address.
> 	ea isRemovable ifTrue:
> 		[html anchorWithAction: [persons remove: ea]
> text: 'remove']].
> 
> Can you give me an example, assuming the existence of ListViews,
> TextInputViews, etc, and making up their API, of how this 
> example would 
> work in MVP?
Yes, I can, lets say is not modal:

WebPersonShell>>createComponents
	personsPresenter := self add: WebListPresenter new
name:'persons'.
	personsPresenter 
		when:#itemClicked: send:#onPersonRemoved: to: self.

WebPersonShell>>model: somePersons
	personsPresenter model: (ListModel on: somePersons).

WebPersonShell>>onPersonRemoved: aPerson
	personPresenter model remove: aPerson.

If you want it modal then WebPersonShell should be WebPersonDialog (a
WebDialog sobclass instead of WebShell). 
Note that in the example I give you, I don't have to deal with wich
attribute of person is editable or wich has to be shown. That's because
I asume the existance of the WebViewComposer tool where you put all that
view information (guidelines to the renderer). I hasn't care about html,
tables, divs, etc. At least in this case you can't say if it's for web
or for a desktop application except by the name of the class. Nice,
isn't it?


> 
> >  Think about it, in the posibilities: a very very
> > cool  ViewComposer, could generate the css automatically for you.
> > Let's imagine an example: you want your application to have a tree 
> > presenter with a customized style, you can put the 
> webTreeView on the
> > shell with the composer, set some general properties like fixed or
> > relative length, background color/image, etc, and specific 
> properties
> > like have checkboxes, getChecboxIconBlock, etc. To make
> this, all you
> > have to do is choose your shell class, lets say for a webmail
> > application you make your WebmailPresenter. Open the 
> composer, you can
> > divide it with two shells (proportionaly or statically divided), put

> > on the top of them a list view for the mail
> headers (in
> > there you also can set wich columns it'll have, getInfoBlocks, 
> > sortBlocks etc.) and below a text view for the body.
> 
> This is a neat vision, and I would love to see how far an
> implementation of it could go.  You say elsewhere that you 
> have started 
> to implement WebShell; any code you can share with us for comments 
> would be great.

I'll do my best to have something more testeable and share it at once.


> > A more strong reason to use MPV, is that in the
> applications I want to
> > make, I plan to use a Role Model that makes a model to be
> presented to
> > the user in a way that is dependent on the rol he/she has
> configured.
> > For instance an administrator will see all the presenters of any
> > model. All posible cards on the web card container 
> > (WASimpleNavigation). A ManagerRole should see more 'cards' 
> than the
> > CashierRole and those knowledge could be given for some objects,
> > colaborating with the role model, that says wich view of 
> the presenter
> > should be enabled for rendering on html.
> 
> Yes, I've done similar things myself, and it works well, but I don't
> see how it relies on MVP.  Each role/model pair simply needs 
> to resolve 
> (through double dispatch, say) to a particular component subclass.

Yes, you're right it can be resolved having MPV or not. I wrote that
because the first time I think of it, I was thinking on how the
subpresenters could be programatically added, but you inspired me with
the google example: the ListPresentersPresenter that I'm working on.

Best regards,

Sebastián Sastre
ssastre at seaswork.com.ar
www.seaswork.com.ar


> 
> Avi
> 
> _______________________________________________
> Seaside mailing list
> Seaside at lists.squeakfoundation.org
> http://lists.squeakfoundation.org/listinfo/seaside
> 
> ---
> Incoming mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.745 / Virus Database: 497 - Release Date: 27/08/2004
>  
> 

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.745 / Virus Database: 497 - Release Date: 27/08/2004
 



More information about the Seaside mailing list