Showing posts with label design patterns. Show all posts
Showing posts with label design patterns. Show all posts

Friday, May 09, 2008

JavaOne 2008

I've been at JavaOne all week, but not blogging. That is partially because of the horrible Wi-Fi at JavaOne this year. Luckily it is good today, so I am blogging before Josh Bloch's Effective Java talk. I also just picked up the new edition of Effective Java, as if I could somehow read the whole thing before the talk ... Probably should have waited to buy it at the end of the day since I won't be reading it until the train ride home. Anyways...

So what's been good at JavaOne this year? Well ... no big news, really. We see more meat on JavaFX and I guess that was the lead story at the opening keynote. It seems like JFX is about where Silverlight was a year ago. The JVM 6, update 10 does rock. You can do so much more with Java than with Flash or Silverlight, regardless of JFX, so it will be interesting to see if people leverage that.

Along those lines, the most interesting session I saw this week was by the guys from Ajaxian, Dion Almaer and Ben Galbraith. Their talk was titled "What's new in Ajax." The subject matter was interesting, but that's not what made their talk so awesome. They are outstanding speakers, and they seem to have a great rapport between them. Their talk seemed very conversational. It also definitely stood out for NOT having to follow the Sun presentation template. It was a Keynote presentation full of cool graphics, animations, and even some short video interviews with some of the top dogs in the world of Ajax frameworks. 

They also did two cool demos, one with Fluid. I fee like such a nov for not having seen this before. It is awesome. They also did an awesome demo where they "threw" a dart at a dart board. The dart board was an Ajax app running the in the browser. The dart was a Wiimote! They used the Bluetooth connection of the Wiimote to send to the PC, and then bridged the Bluetooth stack on the PC to the browser using (drum roll please) a Java applet. The applet was just for communicating with the OS, all of the graphics were in HTML and the interactivity was JavaScript. Very freakin' cool. 

The other good session I went to was Alex Miller's talk on design patterns. Most of this was stuff I was familiar with, like problems with the Singleton and Visitor patterns. What was interesting to me was that Alex showed how closures could dramatically change the implementation of some of these patterns. He showed this for a template pattern. Both template and strategy patterns are kind of obvious targets for refactoring with closures. What surprised me was how a visitor pattern could be refactored using closures. I was inspired to start playing with design patterns in Scala, since that is the future of Java (in my opinion.) I tweeted this to Alex, and he pointed me to some writings on that exact topic. I still plan on doing my own exposition, as I think it will be fun.

Tuesday, November 13, 2007

The Network Application Pattern

    Several years ago I worked in consulting. My company was hired by larger companies to build web applications. We worked on internal web applications, external ones, and even some that were completely consumer focused, like the Washington Post Jobs site. Often we wrote applications that replaced existing desktop applications. Many of these were so called thick clients or client-server applications.
    The list of technologies was all over the place: PowerBuilder, Swing, and Visual Basic. The reasons for the conversions were pretty similar though: make things more easily accessible. It was much easier to say “you need InternetExplorer 5.5 or higher” to run an application, than it was to require somebody to download and install, and stay upgraded to the latest version of an application. The hardest part about these conversions was trying to reproduce all the functionality. You just could not do it, and there were always compromises that you had to work out with the clients on this.
    These days I am starting to think that such compromises are unacceptable. The days of the thin client are coming to an end. At the same time, the days of the thick client are not coming back. Instead a different pattern has emerged, and it is going to win. I call it the Network Application, though other folks have different names and different takes on it. Here is what it is.

Misuse of Big Iron

    To make things as accessible as possible generally meant to require as little as possible on the end user’s machine. The browser wars necessitated this as well. Inconsistencies across browsers required a least common denominator approach. The browser become a rendering device, and nothing else really.
    All the computation required to determine the interface shown to a user was performed on servers. For awhile these servers were Big Iron -- look at how well SUNW did in the late 90’s. Moore’s Law caught up and lots of cheap servers replaced Big Iron, but the usage pattern remained unchanged. Programming languages flourished around this. Look at all the UI frameworks in Java, the explosion of PHP, and the emergence of Ruby on Rails.

Another Shift

    I am not one of those melodramatics who look for a single event and say “this epoch caused everything to change.” Things started changing. Browsers stabilized and Moore’s Law kept moving along. Microsoft’s attempt at subverting web browsers by creating IE-only extensions, ultimately backfired on them. They created XMLHttpRequest, which ultimately allowed for exactly what the Netscape think tank had always hoped for and Microsoft always feared: web applications that were on-par with desktop applications. Well sort of...
    Web applications still have a lot to be desired. As I mentioned earlier, it can be really hard to reproduce a desktop experience in a browser. There are a lot of things going on to solve that, and some of them might even work. Orthogonal to the technologies at play is the pattern of how to program applications that are as feature rich as desktop applications, but can be run from a browser with no software to download or worry about updating.

The Pattern

    The key to the pattern is to stop using servers for creating user interfaces. If you like to think of UIs using the popular Model-View-Controller paradigm, the server should only be a place for Models. Your View and your Controller should be running on a client computer, not a server. Your server will probably serialize a Model to send to the client so it can use it in a view, but otherwise the boundaries should be very clear.
    Why does this help with the problem of creating desktop-like applications? Because when all the view logic is located on the client, there are no limitations to the interactivity. For an example, think about infinite scrolling like you see in Yahoo Mail (I usually rip on Yahoo, so I thought this would be a nice change of pace.) If the view of the list of your emails is formed on a Yahoo server, then to scroll past the bottom means recalculating that view on a Yahoo server, even if it is to show one more email that is just past the bottom of the list. If you had to do it that way, you would not allow scrolling. You would force pagination, like GMail does. However, if you already have the code for creating that view on the client, then all you need on the client is the data to display.

Servers Are for Services

    The beauty of this pattern is that your servers become specialized in serving up data, not HTML. There is still some overhead in de-serializing the request and serializing the response and making it all work over HTTP, but it’s a lot less than the alternatives. Of course it’s not a read-only world, so you’re not just sending out data. You are also receiving changes to the data, either directly, or (hopefully) via a service interface. Just because we’re getting clever with our presentation design, doesn’t mean our middle-tier design can be garbage.
    Notice I used the Service word. This is the same word used by those SOA guys, and it means the same thing. There’s no reason that the clients that you build for your service (in this case user interfaces) cannot leverage the same infrastructure that clients built by other folks use. Now you may want to expose more services to the user interfaces that you built, or maybe you don’t... The point is that if you decouple the so called business logic of your system, then it is easy to build Network Applications that provide rich user interfaces to the end users of your system.

Implementations of the Pattern

    Like most patterns, this was one has emerged from implementations. It is not something I dreamed up in my ivory tower in San Jose. One of my favorites is the Google Web Toolkit. GWT let’s you build things kind of like you would for the old-school thick clients using Swing, but it turns around, turns everything into code that runs on the client. One of my friends was starting to learn GWT recently and I think he was surprised when I told him that everything in GWT becomes static assets that can be served up by any web server directly. They are very cache-able assets as well... There are GWT ways to hook up your server calls as well, and of course this does require a Java application server. But that part of your code can be done in JavaScript, using GWT’s JavaScript Native Interface (JSNI.) The nice thing about using the GWT server code is that you get to use the same object model on client and server.
    GWT is tied to JavaScript, and thus it inherits the limitations of JavaScript. My other favorite implementation of the pattern is Adobe Flex. Flex Builder 3 even has code generators for creating Java or PHP data services for communicating to your Flex application. Flex applications run inside the Flash player, and don’t have nearly as many limitations as JavaScript applications. Flex applications are usually much bigger than JavaScript ones, but are also very cache-able. Bandwidth is becoming less of an issue in terms of user experience, though it is still a cost issue.

The Moral of the Story

    If you are a UI engineer, you should not be writing HTML. You should only be writing code that executes on the client. There are many other options out there. In the JavaScript world, there’s Dojo’s Dijit, the Yahoo UI Library, even script.aculo.us. Ruby on Rails’ RJS has some similarities to GWT, but is not there yet. The Rails guys are still perfecting the last generation of web applications, and have not moved on yet :-) Straddling the JS and non-JS worlds is OpenLaszlo. I would be more enthusiastic about Laszlo if it was using new Flash technologies. On the non-JS side, the two chief non-Flash entities are Microsoft’s Silverlight and JavaFX.
    Now again, these are all technologies that can be used with this pattern. They can also be used outside of the pattern, though I would say that is probably a mistake :-)

Sunday, October 21, 2007

Ning Code

I was leisurely sifting through feeds in Google Reader when I came across a new one from the Ning dev blog. It was about enabling public feeds in private networks. They explained why this was a hard problem (it is) but how you could enable it given some security caveats (so far so good.) One of the keys is changing the source code for your network, which is very cool. That's where the coolness ends. Here's an excerpt:

To change the display code, first visit the file /lib/XG_TemplateHelpers.php and find the function xg_autodiscovery_link(). Remove the if (XG_App::appIsPrivate()) { return; } text (but leave the ?> at the end of that line.)

Next, visit the various templates that might display RSS links. These files are:

  • /widgets/forum/templates/category/list.php
  • /widgets/forum/templates/topic/list.php
  • /widgets/forum/templates/topic/show.php

That list is actually much longer, but you get the point. Umm, hasn't anyone here ever heard of encapsulation? PHP supports OOP, or at least enough of it to easily hide this particular flag so you don't have to remote it in twelve places!

Monday, May 14, 2007

Interceptors vs. AOP

One of the subtle but interesting things that Gavin King said last week at the Web Beans session at JavaOne was how AOP is overkill for most things. He said that Web Beans will support a rich interceptor model (take a look at Hibernate's for an example,) but no built-in AOP. He described AOP as a massive programming solution that is often inappropriately used to solve simple problems. That got me thinking.

We used AOP a lot at Ludi Labs. We were using Spring AOP. I started thinking, could we have use an interceptor pattern as a replacement for AOP? First off, the only reason I would even go down this line of thinking was because AOP presented some problems for us at Ludi. There were the annoying-but-trivial problems such as bloated logs and obfuscated stack traces. There were much more significant problems around performance.

Let's take a concrete example. Any time we store data, there was some "boilerplate" metadata we would store as well. For new data, this would be things like creation time and created by. For updates to existing data, it would be things like update time and updated by. Everyone stores this stuff, and often do it via database table definitions or even database triggers. We weren't storing our data in a traditional database, so we couldn't rely on those common solutions to this problem. Enter AOP.

We created advice for adding this metadata. We were storing user information in a thread local that could be accessed via an injectable stateless service. So it was easy to write advice that could figure out the created or updated info, and it was easy to write a pointcut to specify when to apply this advice.

Obviously this could have been done with an interceptor. But wait, there's more. Once we had this advice in place, there was more boilerplate stuff we wanted to keep track of. For any object we had some common metadata that could be applied to it. This included related objects (for example we could have a jpeg that was the cover art for an mp3,) user comments, and typical web 2.0 tags. We maintained all this together in an atomic object, but that could imply a lot of baggage to pass around.

So we added advice to disconnect this metadata when an object was read. We then re-used the previous advice to re-attach the metadata when the object was being written.

Again, this would have been easy to accomplish with an interceptor as well. There's one more wrinkle. The above metadata could be altered, and everything still worked. For example, an extra comment could be added by one person while somebody else was changing the description of a photo. This just wound up being more advice to write, no big deal.

So is this easy with an interceptor as well? I think this one could be a little trickier. Before we had a clear event in our component lifecycle: updating object data (say the title of a photo.) Now we're updating its data still (adding a comment) but it's data we want to manage separately even though it's persisted in the same data structure. If we are using the same component model, we probably need some kind of bifurcation of logic since these will be the same events. I guess the more OO way to do thing would be to model the events in the component model explicitly, i.e. something like saveData() and saveMetadata() not just save(). Or you could move your interceptor up the stack to distinguish when between these events. That's what would correspond more to the AOP way: define your point cut higher up.

The nice thing with AOP is that you don't have to change any component code to handle this refinement. It's that extra flexibility from having "a huge software solution." If you're able to plan out your needs ahead of time, then interceptors are fine.

This brings up the other bad part of interceptors. Take a look at the Interceptor interface in Hibernate. It has 15 methods. Of course there's the concrete class EmptyInterceptor which provides empty implementations of all 15, so you can extend it and only implement what you need. That's still ugly. You can imagine introducing interceptors on your own components, and then constantly having to expand the interceptor interface and any corresponding helper classes for it.

Tuesday, May 08, 2007

More JavaOne Thoughts

Day One of JavaOne, Java University, is over. I have a few final thoughts. First, I really enjoyed the course I took "Using Java EE 5 and SOA to Architect and Design Robust Enterprise Applications". The instructor, Joe Boulenouar, was very good. You can tell he really enjoys what he does and is very knowledgeable. The class didn't seem as sexy as some of the other ones being offered on things like the Java Persistence API or jMaki, but it was packed with information. Joe did a good job of explaining what are some of the tough things that architects have to think about when designing a system, and then going through a collection of design patterns where each tied back into the architect's checklist. Of course he then also mentioned how various JavaEE 5 technologies can be used to implement these design patterns. If you get a chance to hear Joe speak on something, I highly recommend it.

My only complaint about JavaOne is the lack of AC power outlets. There were a few outlets near the bathrooms or in random places in the halls. It is silly to see developers huddled around these places so they can charge up their laptops. There were a lot of great lounge areas, so how hard would it have been to put some power strips out there? Are they worried about too many people plugging and eating up electricity? Is there a safety issue? Alternatively they could expose power outlets in the lecture rooms so people can plugin and charge while listening to a speaker.