Small note...

> could show it next to the sign-in button for example). The generic
> AsyncCallback#onFailure processing is only used for unexpected server
> errors. On a successful login, then either the presenter or the

If you prefer to have your failed authentication throw an exception
(which is true in my case) you can simply have the Presenter's
callback override the onFailure method, check for the specific
exception you want, then call super(caught) if you didn't get the
exception you were expecting.


On Jul 23, 6:17 am, Thomas Broyer <[email protected]> wrote:
> On 23 juil, 10:20, Kwhit <[email protected]> wrote:
>
> > I think Jason has hit the nail on the head.
>
> > The reason I got uncomfortable with the HasXxx's is that they expose
> > the internal workings of the Viewer (Display in RR's terms). The name
> > getSelectionButton() is a clue. The presenter doesn't and shouldn't
> > care about how the Viewer decides how to trip an action - it might be
> > by some convoluted means like a time out and then HasClickHandler
> > makes no sense.
>
> If you care about "modularization", then yes; but if you are more
> pragmatic and only think about decoupling (to allow testing your
> "presentation logic" separate from the actual "view"), then I don't
> see a problem (much like whether your components know the "place
> service" or the place service is rather an "optional module" that you
> can plug in and out of your app without side effect apart from
> "history management" // see above in this thread).
>
> > The other thing that made me uncomfortable was where Display was
> > defined - in the Viewer implementation.
>
> Er, no, it's in the Presenter (slides 58 and 59).
>
> > As a programmer I find myself being too focused on the internal view
> > when I should be looking at how consumers of an interface see it.
> > Guice for example sees it's core entities as injectors but I see them
> > as factories. As the consumer, the Presenter is the boss here and, for
> > example, a sign in Viewer only needs (g/s)etAccountName(), getPassword
> > () and a 'signIn' callback. The HasXxxx expose a whole lot of other
> > functionality that you don't want anybody using.
>
> IMO, you're thinking here at a higher level.
>
> If I have a text field (for the user name), password field and button
> (to sign-in), and want the sign-in button to be automatically disabled
> whenever one of the field is empty; then I need to listen for events
> on the fields. This is part of the Presenter logic, because:
>  - it works whether the view is implemented in GWT (HTML) or Swing
>  - it works whether I use a text field or password field for the
> password
>  - it works whether I use a Label, HTML, Button, CustomButton or
> PushButton
>  - that's a behavior I that I want to be testable (this is the main
> argument actually)
> Here, HasValue<String> comes in very handy (instead of: getAccountName
> () + addAccountNameChangeHandler(), etc.) what would be missing in GWT
> is a "Enableable" interface for the button.
>
> The point of Ray about MVP is about testability of your presentation
> logic with "pure Java" JUnit tests. You still think in terms of
> widgets but your don't have a dependency on the Widget class (which
> has a dependency on com.google.gwt.dom.*, which uses JSNI and
> therefore requires a GWTTestCase; on the other hand, DomEvent<?>, such
> as ClickEvent, only use JSNI as part of the getNativeEvent(); you can
> mock a ClickEvent by extending it and how it is used by other methods
> such as preventDefault and stopPropagation, but the class can be
> extended and the methods overriden if you really need your Presenter
> to deal with them, and your MockHasClickHandlers would then pass such
> a MockClickEvent to the presenter's ClickHandler).
>
> It's just and only about how to organize your widgets code to make it
> testable easily.
>
> The goal isn't that your test be independent of the presenter's
> internals (if the presenter doesn't even make use of the ClickEvent,
> the mock HasClickHandlers could pass 'null' as an argument instead of
> a MockClickEvent).
> It isn't either that your presenter be independent of the view
> "details" (if your first version didn't enable/disable the sign-in
> button but instead show an alert if one of the fields were empty when
> the button is clicked, you wouldn't need HasValue<String> and a
> getAccountName would be enough; and the time you change your mind
> about your presentation logic, you update both your presenter and view
> code).
>
> You can of course use MVP at a higher level too, but the whole point
> of Ray is to not burn your event handlers inside your "view" and
> instead use "abstract" interfaces
>
> (updated with your followup mail)
>
> > In summary
> > 1/ Define your Presenter logic
> > 2/ Define Viewer interface (without thinking about how the Viewer
> > might be implemented)
> > 3/ Unit test your Presenter implementation
> > 4/ Implement and test your Viewer
>
> I think you were right in your first mail: "define the Display/Viewer
> interface" *thinking* about how you'll implement it, because your
> presenter logic relies on it.
>
> As I said, you're at a higher level here; thinking more about
> modulalization/componentization and abstractions, than about
> pragmatism and testability of your UI logic (don't put words in my
> mouths: this is not a bad thing, just something different).
>
> To continue the reasoning about this example: the presenter would,
> when the sign-in button is clicked, make an RPC call to validate the
> credentials. If I understand Ray's Command Pattern correctly, the RPC
> call would be successful even if the credentials were wrong, with the
> ValidateCredentialsResponse object containing the error (see slide
> #62); so the SignInPresenter would have it's AsyncCallback#onSuccess
> called and could handle the error by e.g. showing a message (the view
> could show it next to the sign-in button for example). The generic
> AsyncCallback#onFailure processing is only used for unexpected server
> errors. On a successful login, then either the presenter or the
> service (using a wrapping ServiceAsync implementation; but I think
> this is actually useful merely for CRUD operations on data) would fire
> a SignInEvent on the event bus.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to