2009-10-29

GWT App Architecture Best Practices (slides+text) Part 3

The source is
http://www.youtube.com/watch?v=PDuhR18-EdM









Now why are we doing all of this stuff? What's the punch line?
Besides having the app isolated from itself for that purposes, we're particularly happy because this gives us easy to write and fast tests. So to write a test in this style, we need our mock objects. We're not using EasyMock here, so we're just implementing these things ourselves. We're going to make stuff that looks like this. I'm going to have a mock version of my ContactsService. And it's going to have these fields here, the lastAction and the lastCallback, and I'm going to fill those at obvious times. When somebody gives me a pretend execute this object, execute this action call, I'll hold on to it so that my test code can take a peek. Throughout the code examples here, I've been leaving off things On this slide, that's not pretend. I probably would have package access I probably would have package access
or even public access to the fields on this mock object because there's not a lot to be gained. By having accessor discipline, I wind up wuth more concise code


We're going to need a few more mock objects as we're working through here. So I'm goung to have to have a nice fake version of that ClickEvent. Because for reasons that I don't remember, we decided you shouldn't be able to do new ClickEvent. But let's not worry about that. We have a mock version of the thing that has ClickHandlers.
This is our pretend button. It's got the same notion of the last ClickHandler that was added to me. I'll hold on to it to that people can find it. When I'm told to... Does this do anything else interesting? Nope. Yeah, in fact, the fireEvent, it doesn't even do anything. Ilt's a no-op.
Our tests don't tend to do that.



Similarly, we had our HasValue thing. We've got a mock version of that that'll hold on to the last value that was set into it. It also, because I have access to... Never mind. That's not a point worth making.





And then finally, we'll put together a bigger, more interesting composite mock object, the thing that implements our PhoneEditorDisplay. So where we would have needed  phone editing widget, remember that our PhoneEditor presenter wants a phone edit widget.
We gave it a nice instance of MockPhoneEditorDisplay, which is made up of MockHasClickHandlers and some MockHasValues. Oops. Oh, well. Some fake accessor methods for those, and again, nice visible fields so that the test can play with it. So that's a lot of work
that we had to do for what's going to be a test for three lines of code.
On the other hand, the three lines of code will probably be more interesting in real life when I need to test, say, "Did I warn the user that they're about to abandon their changes when they navigate away from this page? And when I have tests for the cancel path and for the save path, all of these guys are eminently reusable. In fact you might be asking yourself, "Why doesn't the GWT team provide me "with a prerolled MockHasValues and MockClickHandlers?" And yeah, we should probably do that.



So on to the test itself. We're going to put together our mock world. We've got our fake service. We've got our fake display. We're creating our fake phone object that we wanted to be editing. And we're setting-actually,
it's a real phone object that we wanted to be editing.
And we're setting up another one for how we expect the "after" phone object to look that we're going to send across the wire for comparison purposes.


So on to the test itself. We're going to put together our mock world. We've got our fake service. We've got our fake display. We're creating our fake phone object that we wanted to be editing. And we're setting-actually,
it's a real phone object that we wanted to be editing.
And we're setting up another one for how we expect the "after" phone object to look that we're going to send across the wire for comparison purposes. We're going to instantiate the PhoneEditor, the thing that we actually want to test here. We're going to tell it.
Go edit this phone number,"just like we would tell it in our real code. And then we're going to sneak into our mock objects. We're going to tell the labelPicker, "Okey, the user typed "Work". And we're going to tell our number field, "This is the phone number
she provided." And then we're going to tell the fake save button, "Do a click for me now, okay?" That should have been enough to kick off our presenter object, the PhoneEditor. And now we're going to verify all of that. We are going to sneak into our service.
We're going to see what action it actually requested. We're going to make sure that it was an instance of Update Phone, based on this expected...
Oh. That'll work, actually. It should've been UpdatePhone before,  but they're equivalent because they have the same contactId is the idea. And I did run this test. It compiles and passes. Buh-buh-buh-buh-buh.
And then we get out of the action. They phone object that was actually sent across the wire, we compare the interesting bits of that with what we expected to see, and our test works.






Don't do that anymore. You've got a browser now. You're an AJAX developer. The browser provides all the server state, all the server session you actually need. So that means that when it comes time for rolling updates and servers are falling over and new ones are taking their place, or it means that at your desk, when you need to restart you server because you rejiggered some of the business logic code, what's going on in your browser doesn't even need to notice that that happened. Maybe some calls will be a little bit slower because the cache fell off. But otherwise you're fine.
If you're developing an App Engine app, you've got the Memcache package that's available for you which works really, really well for this kind of thing. So we've got disposable servers.  We similarly want to have disposable clients. I'm afraid I'm going to gloss over this more than it deserves, but the punch line here is, as I said at the beginning, you want to get your history right. As your user is doing things that feel like navigating around your app-- you remember in the AdWords demo, I was clicking around the tree and clicking on-- navigating
into different parts of the app Each one of those places in your app wants to be embodied by a GWT History token, so that as the user hits that back button, she'll return to where she was. If she hits the forth button, she goes on. If she keeps a bookmark, that bookmark actually works, and she returns to the space here she was in the app. If you've done that right, you've got a disposable client. When the user hits F5, or you copy a URL from one browser to another, it just works. Your development life is happier. Your users are happier. That said, the History library is in the traditional GWT way.  It is a bit low-level. Making every bit of your app knowing about History tokens, and knowing to listen for OnHistory token change, and to try to push History tokens if they want to change is sort of nasty. And you want to come up with some kind of an abstraction to isolate the bits of your app from that kind of knowledge. What we did in AdWords was we came up with a package called Place. It's not open sourced. It wound up being very ad-specific. But the pattern itself is pretty straightforward. It pretty much winds up being, just like I have command objects, action objects to embody operations, I've got place objects to embody addresses within my app. They're kind of incarnate bookmarks and each place object knows how to talk to the History service, to push tokens, and read tokens and that kind of a thing. And it's all integrated into the Event Bus. So you remember this picture, where all of my bits of my app are talking to each other.
To introduce place management into this, I'll create something called the place service, which is the only part of the app that's actually responsible for knowing about the GWT History library. So when a bookmark is pasted in, when the back button is hit, when the forth button is hit, place service notices about that. And it announces to the rest of the app, "The user has changed places. Here's the new place that they're going." Maybe it represents a text ad in AdWords. And the bits of the app that need to swap themselves in or swap themselves out
can listen for those more semantic objects, the place changes, and go on their merry way. I've actually run out of things to talk about. Like I said, it always ran long before

=====================================

if I have multiple tables and I have an object that's interested in events from one of the tables and you want to use this Event Bus approach to communicate that, how do I know which table it is without being directly connected to them? Is there-have you guys solved that problem? Without knowing the object itself. Loosely coupling.

Ryan: Yeah. I'm not following the question.

man: Maybe it's too complex.

Ryan: If you want to come up afterward, we can hash it out.

man: I just thought of-- the other question I had-- So I went through the whole property change listeners mess. And I'm looking forward to getting rid of them. But how do you deal with efficiency? Like, now you get an event that this object changed. And you have to update the UI to reflect it. But you don't know exactly-- if you knew, like, this one field changed, you can just go and change one field or move the corner over. But now all you know is something changed. And how do you get around...

Ryan: Well, I know this... I know the something that it is that is actually interesting to me. And you've got more efficiency now, because instead of havings this one-to-one mapping of everything that wants to listen to something and what they're listening to, I've got a lot fewer instances of handler. The execution speed, I don't think, has turned out to be such a big deal. Especially if I'm good about only listening while it makes sense for me to listen. So if I'm the tree of contacts, just, you know, then I'm displaying all of them, well, every single contact event is going to be of interest to me. If I'm the editing UI that's only displaying a particular contact at the moment, it's very unlikely, that some other contact changed, because I'm only one application. I'm not, like, some kind of server handling all of the stuff

man: And what if there is... Our app has, a lot of times, more than one view on the same object in different ways.

Ryan: But you're still-- you're usually not going to have hundreds of views, right? There have-- two or three views, and those two or three views will be listening and maybe will hear some irrelevant stuff. I think that that'll all wash out.

man: All right. Thanks. -

Ryan: Hi.

man: Yeah, my question is, you talked about the importance of being able to bookmark or refresh pages. So going with contact example, you know, it's not just, you know, good enough that I'm on, you know, hit the back button and it knows I was at the contact page. You know, I want to hit the back button and know I was viewing, you know John Doe And then I want to hit the back button again and know, you know, it was Jane Smith. So, you know, I'm kind of wondering, like, in the HTML or in the Web 1.0 or JSP world, you would pass URL parameters. You know, with a question mark Id.

Ryan: That's pretty much how the History library's implemented. Except everything winds up after the hash mark rather than after the question mark. So what you wind up doing is I've got a subclass of place per type of object that I want to be-- that my location is relevant to. So in the AdWords case, we wind up with campaign places, ad group places, and stuff like that. These place objects know enough about the History management system to provide a History token string that includes the ad group Id and the campaign Id. And so boom, it's right back there in the URL

man: And so then does the place interact with the Event Bus, so when it notices...

Ryan: Yes.

man: That a new Id was passed, it triggers an event?

Ryan: Exactly.

man: And notifies pages?

Ryan: So we can go back to our pretty picture here. So the user hits the back button or the forth button. The History event hits the place service, which is where the code that actually implements the History client interface lives. The place service instantiates a new little place object, which...let's see. The place service might actually talk to your RPC service to, you know, say, "Get me this contact" that is relevant to the URL that I just had." And then it will announce to the world, "Hi, everybody, we're at a new place. And this is the contact object that I found at that place." Nobody else has to know about the fact that it happened to live on the URL or whatever else went on.

man: And then, you know, around you Event Bus, how-- I'm just kind of interested in how many different things that subscribe to a single event, like, you know-- let's say I have a tiered navigation, you know, maybe. Or I have top navigation and side navigation. So kind of pages within pages with, you know-- or in terms of GWT, like a panel within a panel. You know, maybe I have, you know, bunch of tabs at the top. And I have a contact tab and I have tabs on the left. I mean, does- do you try and just subscribe to the event in one place and then top down drive, like, "Hey, this was changed," or do you have multiple places--

Ryan: No, it.. People did start talking directly to the Event Bus all of the time for everything. And that was kind of retrograde. If I've just got-- It's like. in the PhoneEditor example. The PhoneEditor... Or in the dependency injection example. We created our contact display and we gave it an instance of PhoneEditor display. PhoneEditor didn't have to know about navigation changes within the app because it had a really tight relationship whith the contact display object that needs to know how to edit phone numbers. There's no reason for that to go crazy with it there. So I don't have a pat answer for you. But I think it's the... the top-level bits of the app that need to appear and disappear are probably the ones listening to, for example, place changes. Maybe other types of events-- you know, contact editing or whatever, maybe there you do want to be a bit finer grained. But you kind of... It becomes a feel thing. I don't really have a simple answer.

man: So have you guys thought about just taking a simple app like this and putting it out there as an example?

Ryan: Yeah, absolutely.

man: 'Cause, I mean, you know, what's out there, I think it was the sandbox or the--

Ryan: Yeah, um--

man: It's nice, but it's not really real-world scenarious.

Ryan: I have been reliably informed that I will be doing that.

man: Well, thanks. Appreciate it. [audience chuckles]

man: Hi. Quick question. I started recently using GWT, and I really like it. My question is more about the History button in general, since you've talked about different design paradigms and patterns. Is History button really, in your view, still a useful thing? Or not History button. The back button, I'm sorry, I meant.

Ryan: Uh, sure.

man: Because now we're talking more and more rich applications. You know, fancy applications. More like desktop applications. You really--you know, once you add-- you may want let them delete it, but not necessarily delete by going back, for example. So--

Ryan: I wouldn't-- You don't want to let them delete by going back. But...especially if you're doing an application like this, where at the end of the day, it's a big bag of objects and I want to navigate around the space that that big bag of objects defines, your users are used to clicking on the thing and then hitting the back button to get back to the place that they were before. I'm certainly not suggesting that you encourage-- that the back button becomes your undo mechanism. I think you'll go insane. But you can't stop your user from hitting that back button. And it's a pretty nice way to work your way through a space.

man: What we did in our app is basically we would stop having the back button at all. So as a result, user get used to using in a different way. More like they're used to using a rich application.

Ryan: I've never had the luxury of working in an app where I was allowed to take the back button away. So..but I wouldn't want to. I mean, it's... There's a reason that the Web browsers got shaped the way they did-- it feels really good. If you're -- I mean -- not every app is this kind of an app. I don't know if the back button really makes sense for Lombardi, where they're, you know, doing more-- I'm doing a big diagramming thing. But for an app like this, I think it's pretty natural. And it's not something to hide from.

man: Thank you.

man: When you build the UI in GWT, it's very developer-centric, usualy. It's basically Swing. It feels like that when I'm building a UI. But usually, UI designers want to make it with mark-up. So there was some talk a while ago about a declarative UI. I may have missed it if that came out. But what do you use for AdWords and are there--

Ryan: We use declarative UI.

man: Yeah?

Ryan: The code's there. It exists. It's called UiBinder now. Its documentation is all public, to make it painfully obvious that we haven't actually released the code itself. We are trying to actually get it out there, and it's just been a question of too few engineers being pulled in too many dimensions. But yeah, UiBinder is used by AdWords. Wave uses it. And getting those guys to ship has kept managing to trump actually open sourcing the thing. It will go out. There's also, in AdWords, there's some code that we rolled to try to-- I implied a lot of Glue there. Of...here's my phone object, here's my string display, copy the string to here, copy the string back, and, you know, that kind of stuff. We managed to generate some amount of that code in AdWords. We weren't super thrilled-- or I wasn't super thrilled with what we came up with. But we've got notions there too of frameworks we'd like to provide to kind of minimize that need. But I don't have particular promises or particular dates to say. We're aware of it as an issue. And we'll get there.

man: Hi Thank you for your talk.

Ryan: Thank you.

man: So the application that we work on, we've done something similar to this with something that roughly translates to the Event Bus. But we don't have all the other constituent pieces talking to the services. Instead, they-- there's, like, this back and forth propagation of events. And can you comment on why that would be--

Ryan: If it's working for you, I wouldn't tell you to change it just for the sake of changing. We..this worked nicely for us because it... I think we have no more events than we actually need traveling around the place, and... Again, you know, for the testing and for configuration purposes, the contact list can stand on its own without having to know who, actually it will be calling into display contacts and that kind of a thing. If you don't have a problem, ther's no reason for you to find a solution. So...

man: All right, thank you.

Ryan: Yeah. Hi.

man: Hi. One of the classic patterns that people use while writing UI code, especially in JavaScript libraries like YUI and other things like that, is having data objects i.e. beings, that they can then take into a widget that is able to take that data object and using a reflection-like mechanism of one sort or another display things into the widget. Manipulate the data, potentially even edit it then spew it back out. There's nothing like that today in GWT, and I'm suspecting very strongly that you guys internally at Google have some way of dealing with this for the large apps that you have. And what are your plans in the future with respect to this?

Ryan: We do have kind of part of that in AdWords. Other teams... AdWords is the... maybe the only app, ore one of the only apps at Google, that's actually this kind of classical, J2EE-style app. And so we don't tend to have broad solutions for those types of things. We have the solution that AdWords rolled for their particular needs. You've probably seen some borderline flame fests on the GWT contributors list about data binding and the need for doing something about this. The approach that we have taken is where you would have used reflection, we will decorate bits of our Ul with annotations, with the name of the particular property - of the model object that that part of the UI wants to display, and we can generate the code that would have been reflection-based for-this text field is tied to the name property. Oh, this thing looks like a JavaBean and it has a GetName method. I'll GetName, I'll call SetName at appropriate times. We want to make that better to generate more of that code than we're generating right now. And there's also similar problems that are coming up on the server side with AppEngine and the ORM objects that you're probably persisting through JDO. A lot of people have found that they've created these crafty little objects that get all nice and persistent for them on the server side, and then they try to serialize them for GWT RPC, and that doesn't work, and how do I get around that without making separate copies and calling set and get and get and set back and forth? I think there's going to be a similar solution to that, but we don't-- We haven't quite come upon it yet. But we are thinking about it actively. I'm sorry, Fred, I was just told So thanks, everybody.







GWT App Architecture Best Practices (slides+text) Part 2

The source is



So, on with the theming. I mentioned that you want to decouple your app. The whole left hand/right hand don't talk situation. The way that we're going to make that happen is the combination of an Event Bus, using the MVP pattern when we have custom widgets to implement, and by using dependency injection, preferably via a tool like Google GIN, which is derived from Google Guice, which all of you --all of you should be attending the Guice tech talks that follow this one, by the way, since you're already blowing off the Wave guys. Guice, Guice, Guice.
Let's go into depth on each of those. Oh, the reason that you're going to do this is because it buys you things. Because your app is nicely encapsulated, you're going to be able to throw away bits of it without the entire thing falling over. You're going to give yourself a spot where you can delay, as long as possible, the slow DOM operations that you might want to be--required to perform. Your application logic will be separated enough from your widget and DOM manipulation logic that the slow things can happen later or never. You're going to find that unit testing is a lot simpler to do.
If I can if it's very clear how I instantiate this particular part of the app, it's going to be ease for me to test that particular part of the app without having to swap in the other 500 parts of the app. And if I do this right, I'm going to have really fast unit tests that I can execute in a JRE rather than in a GWTTestCase. So unit tests that execute in microseconds rather than in the 20-whatever seconds it takes to launch GWTTestCase these days. Which time we are improving, let me say. But it'll never be the same as simply not doing it at all.



So what's an Event Bus?
Let's show you first what an Event Bus is not. You're writing your app in a typical style, and you've probably created yourself
a bunch of model objects in our address book that are probably contact groups and contacts. And they got property lists. They're throwing property change events. Each one has a list of listeners that are watching for changes to the thing. And we'll start adding in bits of our UI. We've got our contact group list UI, I We've got our contact group list UI, which is going to have a listener attached to each one of these group objects. And then we've got the list of contacts within an individual group that's listening, attaching handlers-- event handlers to some of those contact guys. We probably have a display with individual contacts
that the list UI needs to know how to swap in. And the contact list is going to want to edit these things, and these are all going to be listening to each other for update notifications, you know, show yourself, hide yourself, I'm done now.
And then marketing comes in and says, "We don't have enough bread crumbs on this thing, and that Window Title's looking kind of sloppy."
We got kind of a messy world here.
We've got a lot of handler objects that we've instantiated. We've got a lot of things that we can forget to decouple when it's time
to tear things down. It's not a fun world. I won't even talk about testing. It's an excellent profile. So we can reduce this coupling
in a couple of steps.




But first, we'll introduce our Event Bus.
This thing on the side of the app that everybody has access to, where they can listen for the stuff that has happened in the application that might be of interest to them without necessarily needing to know who was responsible for that event in the first place.
So, for example, when the contact list UI wants to tell the world, "Hey, the user thinks that it's time to look at the details of contact X," it can just post that event to the Event Bus. And whatever parts of the UI are responsible for actually showing the user contact display, contact number X can take care of doing that. And it doesn't have to know that it's -- this week, it's the contact list UI that's responsible for doing that, even though next week it'll probably be some other gesture that some UI designer-- respected UI-designing colleague -- came up with. But you see we still have a lot of mess in the middle there. We've got all these property change listeners that I keep clearly implying I don't think you should have.


And what I espouse doing instead is just getting rid of that model core. Not saying that you don't have model objects, just saying that they're not terribly of central importance. Instead, remember that we know that everything that we do is asynchronous. Let's just push that asynchrony right through to the bottom of our application. When the contact display UI is ready to display somebody, it'll tell the RPC service, "Hey, get me contact XYZ. I've been told to display him." With any luck, that's cached, and so my callback fires right away, and I've got him immediatly. When the editing UI needs to mess with that contact, and change his data, he's going to tell the RPC service, "Hey, I've got an update for you. Push that down to the service for me."
When the response comes back in to the RPC service, he will announce to everybody who is interested, "A contact has hanged. "Here is the new copy of that contact. Why don't you all who are interested display that thing?" And everything is nicely isolated from each other.



So let's look at what the code would shape up as for that. You'll remember this showContact method that we wrote earlier. We're going to add a little bit to it.


We're going to start paying attention to just which contact we're looking at at the moment over here in our contact display UI.
So just something as simple as holding on to that Id object so that we know who's important to us.



Before we ever tried to show a contact, we attached ourselves to the listener bus. Sorry, the Event Bus.
We're going to use a GWT class to actually instantiate our Event Bus, because that's simpler than writing our own With GWT 1.6, we revamped our event handling mechanism. And at the heart of each one of our widgets is a handy class called the HandlerManager.
There's no reason that you can't use your own instance of HandlerManager to provide your app-wide event dispatch services. So our contact display has somehow magically gotten its hand on the HandlerManager Event Bus instance for this app.
And he's attaching to it a typical event handler. You've created for yourself a custom Change Event type called ContactChangeEvent. And you're implementing your custom event handling interface. So when a contact change comes in, you're going to look at the new contact object that's hanging off of that event. see if it's the one that you're actually displaying, and if so, do something about it.And a subtlety here is that you don't really know if that's the one and only copy of this contact, if it's one that's been handed to you for your purposes at this moment. The contact goes from being of central importance where you might be attaching handlers to and from it to this kind of ephemeral, disposable thing you can kind of wad up and toss on the floor when you're done.
But don't change it, 'cause other people might be looking.





Continuing with the code, let's move over to the RPC service itself. What we're doing here is we have wrapped the GWT RPC service that we defined with somebody who's implementing the interface itself. In this particular case, we're taking that execute method that our RPC service provides and we're overloading it to provide specialized handling of this UpdateContact type of action.
And the interesting bit is that we are wrapping the callback that the caller gave us with our own callback, which on a successful response is going to update whatever kind of a cache we're maintaining.


It'll fire off the real onSuccess result for the real callback, and then it's going to tell the rest of the application, "Hey, contact changed. You might want to do something about that." It's as simple as that.


So continuing with our decoupling theme.
I keep saying "MVP, MVP, MVP."
And I did not say MVC. Now the odds are that when you got out of the five or ten years you spent doing JSP and Web 1.0 app, you kind of dusted off some desktop knowledge or somebody who had once done that kind of work told you, "You know
what we should really be doing "now that we've got these widgets is model, view, controller."
And it's this kind of triangular thing. And the model throws events. And then the view throws events. And the controller messes with both of them. And I forget what code goes in the controller and what code goes into the view. And no two people will give you the same answer for what MVC actually means. There are a handful of guys who wrote Smalltalk-80, but thev may well be retired.
You also wind up with a problem here that, like I said, some of your code landed in the controller. Some of it landed in the view. You need to test it all. And the code that landed in the view is not going to run real fast. It's messing with the DOM. And you either need to have a pretend DOM there If you're lucky, which we don't provide you-- yet-- or you need to fire up a real DOM. And those tests are just not going to run fast.



So what you want to do instead is use the model, view, presenter pattern. We found ourselves implementing this style kind of by accident, just trying to isolate our code from tests.
And then some people who are brighter than me were reading Martin Fowler's blog and saw that he had already invented this pattern before most of us were professionally active and had called it MVP. So we call it that too.
Then what you're doing is just much simpler layering. Your view class down there at the bottom is the only thing that actually knows anything about DOM elements and widgets.And it's a source of things like KeyboardEvent and ClickEvent and very
browser-specific events. The model at the top, we're familiar with at this point. It's this kind of overglorified bag of setters and getters that we're using because we decided we don't like property change listeners. And that leaves the presenter in the middle
as the only object that has anything that's really worth testing. This is the thing that knows how to take,say, a contact in one end
and take its values and cram them into a bunch of text fields on the other side, listen for changes to those text fields, and interpret them as something-- as values to push back into the model.

 
When it comes test time, we can ignore that silly little collection of DOM widgets that we created and replace it with a bunch of mocks. And in fact, we can even use the GWT MockUtilities package, which I think was also introduced in 1.6, to use something like EasyMock or J Mock-- or actually, there's something called Mockalicious now, which looks interesting--to provide fake test fields, fake this and fake the other, and run them under a JRE.
Although today I'm actually not going to show you doing that, because I found that for the pretend code that I'm putting together, it was easier to do the mocks by hand.



So let's get concrete again.
In our address book, we are doing things like editing contact details. Say we're going to edit somebody's phone number.
So a phone number looks like that, it's got an Id, it's got the telephone number, and it's got the work, home, mobile, babysitter label.

 
The UI probably looks something like this. I'm sure we've all seen that numerous times.




And all of the interesting stuff is here at the presenter layer where we're going to implement a thing called the PhoneEditor, whose job in life is to take a phone object in one end and a phone UI in the other end and make them all go.


So the PhoneEditor probably looks something like this. At least it does when I write it. Oh, the brace is in the wrong place. Damn. It's going to define an interface for the kinds of widgets it wishes it was talking to. And you'll note that I'm describing things like a save button and a cancel button and a number field. But I'm not calling them "buttun". I'm calling them HasClickHandlers and HasValue. These are characteristic interfaces that the GWT widget set is littered with. And if I define my display interface in terms of these characteristic interfaces, it becomes quite easy at test time for me to provide mock instances of those things. A lot of people think that providing this display interface is more trouble than it's worth. And they will tend to give their presenter objects actual knowledge of the specific widgets,
like text field, like button. Not a big deal, because you can, again, use EasyMock or its like to put in fake versions of those in the JRE. But that made the slides too big, so I didn't do that today. So we've got our display interface.

Oh, there's another cheat  that I'm doing in here. I have implied that GWT has a pop-up widget that implements the HasValue interface. It does not. We ran out of time. I think it will have such sooner or later. Maybe even in the 2.0 timeframe, I need to talk to my boss about that. But in the meantime, it is no big thing for you to write your own HasValue wrapper around the list picker as you're going to use it. So full disclosure out of the way. We did. And it didn't take us hardly any time at all.



How are we actually going to use the thing? At some point in the lifetime of our PhoneEditor, we'll be handed our display object, which--don't tell enybody-- it's a composite. We'll hold on to that thing. We'll attach a few handlers to it. OnClick of the save button, I want to call my doSave method. OnClick of my cancel button, I'm gonna do my cancel method.



Sooner or later, somebody's going to tell me to edit a phone number. to the phone instance that I'm editing. And I'll do that simply by holding on to the phone instance that I'm editing. I'm implying a kind of sneaky thing there with that static method on phone. I'm figuring that the instance of phone that I'm editing may not turn out to be the one that I actually want to keep. And to make sure that I'm not going to accidentally mess with the phone object that other parts of the app might be trying to display, I'm going to assume that I defined a kind of a clone style method on my POJO. You can follow this convention or make up something else. This is more or less what we did, except our code was uglier. Once I've got this safe copy of the phone, which I can toss away when I'm done because model objects aren't special anymore, I'll just tell my display to show the number and update the label picker and that kind of thing.


Now let's actually save what the user has done. Again, it's a simple thing to pull the values back out of that display instance and then fire off my nice asynchronous service method. When I hear back that my POJO-- my phone number was updated successfully, I'll tear myself down, whatever teardown means for my PhoneEditor If there were errors, I'll have some error reporting and rendering convention that I will have implemented, and I'll display those things there.
Obviously, I'm glossing over a lot. And you'll call me on that at question time. But until then, I can just get away with this.



So let's talk about dependency injection. I'm sure you've all heard the term. And you've all been meaning to adopt it, and it seems like a good idea, but maybe on my next project. Dependency injection ain't no thing. It is just a pattern. All it means is that instead of having global instances of my services that I reach out for, like GetEventBus.singleton instance, GetRPC.singleton instance. And instead of using a service locator that I kind of cram full of every interesting property of my app and shove it down the throat of any part of the app that might want it, I'm very explicit, preferably via constructor arguments, about just what it is this particular object needs to exist in a useful way. DI is really not at all hard to do manually. And in fact, AdWords does do all of its DI manually, because we didn't have any way to do it automatically at the time that we started the project.
In the interim, there was a GWT developer on another project... this is public. You know the contact manager in the personal profiles that Google is starting to flog these days? The group that put that together were a big fan of the Guice dependency injection framework for Java, and they wrote their own version of it, called GIN And now more and more apps, internally and publicly, are taking advantage of that. You can find both Guice and GIN at the URLs provided there. There are also talks comming up an Guice right after this one, and if you leave this room, I suggest you go to that room. but it's on your little badge-y thing.
I had a picture of Snoop Dogg here for the GIN and Guice thing, but the lawyers wouldn't let me do it. So, sorry.



So what does the code actually look like when we do something like this? Well, let's start at the bottom of it. Let's assume that we have a widget that is a widget in the MVP style that is my contactViewer. And that's kind of the heart of my app. And when the contact viewer is ready to go, it wants to get the root panel and just start to jump into it. So what do I need to do to instantiate my contactViewer? Well, I'm going to look at its constructor arguments. It needs its ContactWidget, probably implementing its display interface, because I wrote it.
It's going to need an instance of that PhoneEditor MVP presenter thingy because it's going to-- it uses that end line. It doesn't go talk to it through the Event Bus. Not everything needs to talk to everything else through the Event Bus. Things that want to deal with each other directly-- there's no reason that they can't have handles onto each other. We still like composition in this world. It needs the RPC service to ask for the contacts, and it needs the Event Bus to listen for changes to the contacts that it cares about. So it's going to get its hand
on the ContactWidget with a simple "new." It's going to get that PhoneEditor with a simple "new" -- ooh. But the PhoneEditor has dependencies too. It's going to need a widget and it too needs its hands on the RPC service. But we're not really using the actual RWT generated
RPC service. We have our wrapping thing around that. So let's instantiate our CachedBatching rpcService, into which we will jam the one that we GWT.created to do the real work.
And then finally, everybody seems to want this Event Bus thing, So we'll instantiate one of those. So that's kind of a lot of code, but it wasn't really hard to look at.

 
Part of the payoff starts to come when new dependencies appear. Marketing has heard about this Google Voice service, and they're absolutely convinced that we should have Google Voice integration with the PhoneEditor. So we're going to add that by instantiating the voice service. We're going to change the PhoneEditor constructor. And nobody else knows about that change. Even though the PhoneEditor is fairly far down in our tiny little stack, the thing that needs a PhoneEditor because it never instantiated it itself doesn't need to know this PhoneEditor now needs the VoiceService. And I didn't have to add a VoiceService argument and a VoiceService argument and a VoiceService argument at every level in my code. But still, you can see that this is going to grow into a lot of kind of grungy code to maintain, and a big list of instantiation to do all at the top.
If you were to use a framework to do it, something like GIN-- talk-- Actually, there's no talk about GIN itself today. I don't want to imply that. But there is a talk about Guice. And GIN is just like Guice, but on the client side. Anyway, if you use GIN correctly, and using it correctly is easier than using it incorrectly,



the code winds up looking like this.
So I highly recommend it.








2009-10-23

Forty-Two: SF JUG - GWT Can Help You Create Amazing Web Apps

Forty-Two: SF JUG - GWT Can Help You Create Amazing Web Apps

Video "Voices That Matter: GWT - Architecture Best Practices"

Video "Voices That Matter: GWT - Architecture Best Practices"

GWT App Architecture Best Practices (slides+text) Part 1

This is material of conference, that I have learned and for everyone, who are interesting in GWT programming.

The source is


Ryan:
Hello. My name is Ray. And I'll be talking to you today about GWT application architecture best practices. We tried to find a drier title, but this is the one that won. I am stunned, amazed, and flattered that you all are here when you could be eating lunch or learning about Wave. So, thank you very much for sowing up. I was going to go get lunch myself if you hadn't. So, I'll warn you also that all my rehearsals of this have run long.  And I've responded to that by adding more slides to the presentation, so I'm probably going to do a lot of mumbling and a lot of talking fast. And we'll see where it goes.




So what are we talking about today?  This is about how to put together a nontrivial GWT application. Something that you actually want to ship. Something that you're going to have more than two or three people at a time working on without stomping on each other's toads.Toes.
We're going to look, in particular, at the client side because that's where I tend to pay attention. And what we're really exploring here are lessons that were learned over the past year building the new AdWords user interface. 
AdWords is a small product at Google. You may have heard of it. And it's recently been--the user interface of that has been revamped from the ground up as a GWT application.



But first, let's go to the last slide of the presentation. If you take nothing else away today, there are three things that you really want to remember. First thing, which I'm not going to talk about much at all, but still, you want to remember it, get your browser history right, and get it right early.
One of the first things that you should nail down on your app if you want it to work is what the back button and the forth button are going to do to your users, how they're going to be bookmarking things. GWT gives you a very nice history library to take care of that, and if you apply it early, it's easy. If you apply it after the fact, and try to retrofit it in, not so easy.
The next takeaway point is you're going to use an Event Bus as the backbone of your application to let yourself-- let you make sure that the left hand of your app has no more than a nodding acquaintance with the right hand of your app. Preferably trough conversations brokered by a neutral third party.
And then finally, you're going to start saying to yourself, "DI + MVP FTW." Which is to say, dependency injection and the Model/View/Presenter pattern for the win.
And I promise that that'll all make a lot more sense in about 50 minutes or so.


So let us start with a demonstration of the app that I mentioned, the AdWords Ul. Which I, of course, forgot to cue up. So give me a moment to rectify that situation. Yeah. We might just blow off this part of it if I can't get my act together here. There it is. And it has decided to reload. Good.
So this is live right now. I'm looking at the production site. If I run into glitches here, there are people in ten countries around the world, a number of users-- which number I have been cautioned not to disclose-- but they'd notice. You can see that this is a pretty traditional kind of table full of data sort of app. But we've got nice little widgets like the GWT Incubator tree view, fast tree view, helping us guide our way through things here. Our users are going to do things using the paging scrolling table from the GWT Incubator to make lots of edits of their data.





Maybe several fields at once in that kind of a thing. Or I might want to type around and change my matching and change my CPC. I forget what that means, actually, although this is my live account. So I'm not going to actually commit any of these change that I'm making. They might take advantage of the GWT visualization stuff that you might have learned about yesterday to show graphs and such. There's my pretty graph. I'm not doing so well,really. Maybe we're going to compare my click-through rate to the number of clicks that I get and see if there's a correlation there.
Yep, there is. So this is the app that we've built with a team of more than a few engineers. I really forget the handful, but the sizeable handful has grown lately. And we're all able to commit changes to this and test portions of this without necessarily talking to each other every day and destroying each other's code.



So let's get back to the presentation.
So we've got three major themes that we're going to talk about here on your way to making no bad apps the AdWords way. You're going to embrace the asynchronous nature of you app. You are an AJAX developer. And the first word in AJAX is "asynchronous." - Let's just not kid ourselves. You want to always be decoupling your app. Like I said, the bit over here
and the bit over here just shouldn't really know much about each other. And finally, you're going to strive to achieve statelessness, so as various bits of your infrastructure fall over, the other bits aren't bothered by it.
So, embracing synchrony. These Keynote builds, man. I can't get enough of 'em. Yes. The "A" in AJAX is for asynchronous. There is nothing interesting that you're going to do in your application that isn't going to, at some point or another, require some kind of an asynchronous callback. So you need to just come to terms with that fact. You don't want to spend a lot of energy trying to create little synchronous bits that you can call once everything is swapped in, because you've got better things to do with your time.
And if you do it well, it's really not such a bad thing. 



So here's an example of what you might start out trying to do. Through the talk, I'm going to assume that we're writing an address book application.A contact manager. Could you all turn you cell phone ringers on, please? The first thing you're going to do as a good developer is you're going to create your data objects, your model objects at the heart of your app. And at the heart of an address book we have contacts.
And my contacts have things I like a name field, and they have ContactDetails. ContactDetails are an interface to cover phone numbers and street addresses and mother-in-law's birth date and that sort of a thing. And the mistake that we made here is that we are downloading the kilobytes and kilobytes of ContactDetail information at the same time that we're downloading our contact objects.
At least, that's what I see implied here. That's a mistake. The odds are that you want to get your hands on that list of contacts
with as little information as you need as possible to display them to your users, and then you want to move on from there to fetch just the details that the user cares about.



So probably you want a structure that looks more like this. My contact comes down with a list of Detaillds. Some kind of opaque Id object. It's probably a string under the hood. But we're all Java developers here. We like our strong types.
And that way we don't accidentally ask for a contact with a phone number Id. Another small change I made here, which is kind of sneaky, is that instead of using a list of ContactDetails, doing the Josh Bloch thing and correctly providing an interface for my field name rather than the implementation class name.
I'm actually being very straightforward about the fact that this is an ArrayList that I'm looking at. I picked up this superstition
from a talk that I may have misunderstood on optimizing GWT RPC. Where if you know that all you're ever going to send across the wire are array list instances, you don't want to the GWT RPC-- the magic generator-- a chance to try to pick up every other possible implementation of the list and accidently compile that into your app. Small point.




So here we are, writing everything asynchronously. And thinking to ourselves, "This is really going to suck."






It doesn't have to. If we wrap our asynchronous calls and asynchronous operations in the command pattern, life can be pretty good. A command pattern is a kind of a thing you do where instead of having call for this-- you know, a "do this" method and a "do that" method and an "update the other" method-- we have objects that embody such calls. So when it's time for me
to get ContactDetails, I'll make an instance of getContacts command, and I'll hand that off to a command processor and receive back in return a "got the contacts" response. Every action I want to take with my app, I encapsulate into an object like that.

And because I have all of these nice little command objects, 
I've got a nice unit of currency for implementing caching policies. May be whenever I see the same GET request twice, I'll cache away the response I got last time and just return that to myself immediately. Not bother with a server-side trip. 
I've got a place where I can do batching mechanisms. If I see five getCalls in succession that aren't interlayered with updateCalls, I'll have a timer going where I can collect all of those guys and put them into one do this group of operations command, and put them into one do this group of operations command, send that over to the wire, over wire in a single HTTP request, rather than sending them off as bits of the app ask for them.
I got a place that I can centralize my failure handling. So that every time I'm making one of these async calls, I can inherit the "oops, something went wrong" behavior rather than having to call it out in line there. This also, if I want to get a little bit forward-looking about this, since I'm being honest with myself about the asynchronous nature of what's going on here. I've done all of the hard parts of chopping up my app into bits that can be code split at GWT.runAsync points. 
I won't go into detail on GWT.runAsync, because I'm sure you've been hearing about it for two days, but do it this way and you're halfway there. If you ever read a book on "how I'm going to implement undo and redo on my application," the odds are the term "command pattern" is going to come up. And you're already working that way. Because you're so clever, you're halfway there. And then finally, the work that you've done to isolate yourself  from all of this RPC. You've got a nice funnel point at which you could slip in your HTML5 persistence type of code when you decide you want to get into offline work.



So. let's look at some actual code here, how we might implement something like this. Are there any AdWords engineers in the audience? I can say anything. Okay. They won't actually recognize this interface. It's not exactly what they do. But there are tools


that they created specifically for the project, which when you pull back the hood, this is what's going on there.
So I assume most of you are GWT developers or you would be off looking at Wave. You probably recognize the bottom half of this slide where we are defining a GWT RPC service. When we're working in this style, we have a single service, and that service provides a single call, which is basically that "execute" word there. Do something for me, and then return to me the response.
What happened?
And then the various somethings that we want our app to do are going to implement this Action interface, which we couldn't call Command because that word is taken by another GWT class.

So an example of an Action object that we might write would be this GetDetails thing. Remember that we are working on our address book, because the world doesn't have enough address books. The command will be something as simple as I'll instantiate the thing. I'll give it a list of the Ids of the details that I want. On the server, I'll do something clever to actually fulfill that request and



send back across the wire a GetDetailsResponse object, which has this nice ArrayList of the details that I can then go and render.
Now, I'm not trying to say what the granularity of your operation should be when you write your app. I'm implying a pretty verbose world here where I've got 500 different flavors of Get command, based on my 500 different model objects. Maybe you want to do something a little bit more generic and just have a single Get something command that's parameterized based on the type that you're fetching. Maybe it's going to make sense for your app to be more coarse-grained. Maybe you want to write actions like, "Get me all the stuff I need to render the first page of the Ul." The level at which you break stuff down is up to you. I'm just trying to pound home the idea to pound home the idea that you've got objects that embody what it is you're trying to ask for and the ways you ask for it. And I took that digression one slide too early. We've had our...whoops. We have our action class.
We have our response class. To make the code a little bit more pleasant to deal with.




we're going to write probably a third class which is a custom subclass of the asynchronous callback that happens--is handed to each GWT RPC call. This gives us a spot  to write failure handling that the application code can inherit and not have to worry
its pretty little head about. Maybe we'll pre-chew the response a little bit to keep everybody from having to write the Get, the Get, the Get, the code to actually get the meat of the response.


So what I actually will end up writing in my app when it's time to render a contact or something like that is a method like this showContact thing. Where I somehow magically -- we'll discuss it-- got my hands on the service. I've called this execute method.




I've given it an instance of the Get Details command that I want it to run. And I've instantiated my callback GotDetails so that once I've got all my information, I can call renderContact, I can call renderDetails,  and go mess with widgets and stuff.
As Java goes, that's fairly concise. We don't have anonymous.. we don't have closures and probably never will. But this is about as short as it's going to get in a Java sort of world.