Advertisements
|
||
|
There's an old adage that one ends up writing the same software all over again, except each time using different technologies. That's true of developers who have become domain experts by virtue of long stints in a given industry, such as e-commerce, financial services, manufacturing, or HR.
Business problems tend to change less rapidly than the available technology solutions do, giving us the opportunity to, hopefully, improve on earlier attempts with each new iteration. User interfaces are an example of rapid technology development. Progress in UI toolkits partly addresses the changing needs of user interaction—for example, presenting user interfaces on mobile devices—and partly attempts to make the programmer's job easier.
The extent to which newer UI toolkits benefit a developer becomes apparent once you have worked on similar applications using different UI technologies. In this article, I relate my experience in moving from HTML to Swing, from Swing to Ajax, then from Ajax to Flex in very similar applications, and reflect on whether each of those technologies offers greater convenience to the developer. The application in each case addressed the same basic problem: it allowed auto dealerships to process their inventory and interface with financial services companies.
Although simplicity was perhaps its greatest strength, there was something inelegant and unsatisfactory about the HTML of the mid-1990s for business application UIs. To be sure, one could use the nascent Java Servlet API to generate HTML pages on the server, dedicating a large portion of an application's code to building HTML had something unattractive about it: Any change in the view had to load an entire page, and UI state had to be transferred back and forth between the server and the browser.
In a login page, for instance, suppose a user entered his email address and password, and then realized he had not yet created a user account. Web sites typically offer a Create a new account link next to the login button. Without client-side scripting, the new account link would have to go back to the server, which then would render a new page with additional fields to fill in. If the user reloaded his browser window, the system would have to remember to render the "account creation" versus the "login" state. As well, the account creation page should ideally reuse the email address and password the user earlier entered.
When Swing became a viable option, I thought I could finally benefit from making my user interfaces more interactive, reuse all those attractive UI widgets, code my UI entirely in Java, and deliver my application as an applet inside a browser—if I could only wait long enough for the Sun folks to cook up a practical and universally available way for users to access applets.
I waited, and waited, and waited, and in the meantime spent many a precious day writing HTML-generating code on the server. And then I waited a bit longer, and during that time learned to use new-fangled server-side frameworks to make the HTML generation more bearable. And then I waited even longer, and came to accept that applets would just not happen.
What did happen, though, was an opportunity to work on a similar application from the ground up, using any UI toolkit I wanted. Server-generated HTML was just not going to cut it this time. Applets were not practical, but Swing was thriving, and IntelliJ just showed the world what one could accomplish with a purely Java UI.
That's how my desktop Swing application was born. We used the new JNLP APIs and deployment mechanism, and was fairly successful in allowing users to update their JREs and install our app on their desktops with a single click. There it was: Swing running on users' desktops, in a business app written end-to-end in Java. Swing provided the interactivity that HTML couldn't, and its component architecture allowed me to focus on business-specific code.
Over time, though, Swing nirvana gave way to Swing realities. Although I did not have to create layout and rendering code in Swing, implementing new features was still a big undertaking: a lot of code had to be moved and refactored. Swing proved to be rather verbose: Defining a form that would have taken a few lines of HTML required a much more careful and laborious approach (even with the excellent JGoodies FormLayout). UI state could only be updated from the Swing event handling thread, and even then any update necessitated careful code review to avoid inadvertently hanging the UI.
Swing clearly needed a framework for common tasks, similar to server-side enterprise Java frameworks, but it didn't have one. There was some excitement in the Swing community when the JCP published the specs for the Swing Application Framework, JSR 296; but JSR 296 didn't go very far, and neither did many of the third-party additions and enhancements to the core Swing libraries.
That was perhaps in part because developers started to see promise in the advent of Ajax frameworks at just about that time. After all, Ajax allowed one to write apps that appeared to rival what one could accomplish with Swing, except that these apps ran inside the browser, alleviating the need for client-side JRE updates and installations. In addition, some server-side frameworks, such as Rails and JSF, took great pains to integrate with a few Ajax frameworks in the presentation layer.
As luck would have it, the opportunity arose to implement yet another iteration of a similar application to what I had worked on before. I chose Rails this time—partly because the Rails folks advocated taking extended lunch breaks and siestas instead of spending long hours at the keyboard, partly because Rails seemed to provide a well thought-out integration with client-side JavaScript frameworks, such as Prototype and script.aculo.us, but mostly because I needed a reprieve from Java verbosity.
Developing the third, Rails-based iteration of my application started out with a sense of pure joy that I just did not experience with Swing: Ruby coding was fun, and Rails' tie-ins with client-side JavaScript provided the application with much Ajax flourish. Our users were happy, and our managers were pleasantly surprised at quick turn-around times.
Happy users tend to request new functionality, and Rails lived up to its promise of facilitating agile development practices. Up to a point, that is. In one case, users wanted to have a data grid with several thousands rows pre-populated, and the ability to scroll and sort that table on the client. The excellent Yahoo YUI interface library came to the rescue with its robust data grid component. While YUI had an elegant and very capable design, it did not always play nicely with some other Ajax toolkits and libraries we were using. That was hardly the fault of library writers, as JavaScript clearly was not conceived for large-scale application development.
As our application became even more popular, a few performance issues cropped up here and there, and we had to start thinking of scaling long before we would have reached that point with Java. Part of the scaling issue was rooted in the UI architecture, though: Rails made things easy when computation was sent to the server and the UI was merely doing presentation. That was a bit of a throw-back to the HTML-generation days, and a move away from Swing, where lots of user interaction could be processed directly on the client.
The further I got into using YUI, the further I departed from the beaten Rails path. After a while, the Rails and Ruby parts of the app started to look like a JSON server, merely serving up requests from the clients. Would server-side Java not have done an equally fine job at JSON serving, but without the performance issues? I wondered.
Most application design emerges over time, which makes refactoring an important tool in sharpening the robustness of a codebase. Refactorings come in various sizes and shapes, from renaming of private methods and variables to moving and renaming classes across packages and modules. Larger refactorings often incorporate hindsight that, in turn, can make a codebase simpler.
Having gotten used to IntelliJ-style refactorings with Java, I was, perhaps naively, surprised that refactoring a largish Ruby/Rails application requires far more finesse and caffeine. Unless one has an iron-tight test suite, covering virtually every aspect of the code base, big refactorings of a Rails app can be an exercise in guts and bravery. I could never be sure if I inadvertently broke something, even though my tests all passed. Mistakes did not happen often, but I would on occasion get calls from users, compelling me to log into a production server, fire up vi, and make the needed changes then and there—an absolute worst practice.
But it was ultimately the desire to create more engaging user experiences, especially in the presence of larger amounts of data on the client, that led me to look into Flex. Flex just then reached its 2.0 release, making use of ActionScript 3. Coming from a Java and then Rails/Ruby background, Flex's Flash heritage seemed foreign, even alien, to me: I had not much interest in creating Flash animations or movies; I was interested in business applications.
ActionScript 3, on the other hand, had a greater appeal, mostly because it was positioned as a superset of the JavaScript available in Web browsers. Indeed, until about two years ago, ActionScript was to be the "next-generation JavaScript." (Adobe's hopes to that effect were then quashed by standards-group politics.)
From my JavaScript/Ajax development experience, ActionScript 3 did solve major JavaScript shortcomings. Even though JavaScript's prototype-based classes are a powerful concept, ActionScript 3 added Java-like classes to the language. It also provided packages and namespaces. And, most important to me at the time, it came with (optional) static typing.
ActionScript's language improvements were a nice feature, but I already enjoyed most of those benefits when programming with Java and Swing. What Flex had that Java and Swing didn't, was a very well-designed, visually appealing UI widget library; and, on top of that, the ability to seamlessly embed Flex content inside an HTML page. That sounded like some combination of Java's and Ajax's benefits.
Our Flex-based application has been in production for two years. During that time, we evolved the app with new features, and implemented an almost complete UI makeover, moving from a browser-based app to one accessed via a desktop icon and delivered on the AIR toolkit.
Before comparing from a developer's perspective the various UI technologies I used throughout this application's evolution, I must note that all these technologies are capable of achieving similar results in terms of usability and visual appearance.
Recent advances in HTML and CSS make Web UI's indistinguishable from user interfaces created via non HTML-based technologies: browser performance, built-in support for SVG and video rendering, and CSS-based layouts can make HTML-based UIs very polished. Swing, while looking the October rose when used with its default look and feel, can also be visually attractive in the right hands, as Chet Haase and Romain Guy showed in their book on Filthy-Rich Clients. Finally, Ajax toolkits, such as YUI, provide sharp-looking, skinnable widget libraries.
How easily a developer can achieve an attractive UI is another matter, though. While much depends on a developer's sophistication and knowledge, creating attractive-looking UIs requires different levels of effort with each of these UI approaches. Swing programmers can achieve virtually any UI effect and appearance, because Swing gives the developer access to Java's low-level graphics primitives. Such low-level programming, while a great deal of fun, is not always practical in the context of a business application. It is also possible to apply third-party look-and-feels to a Swing application, which can improve the default Swing appearance considerably, and with much less effort.
HTML and CSS-based UIs are often developed in conjunction with designers. Separation of designer and developer responsibilities may be appropriate in many cases, and even necessary; but it also incurs additional cost and complexity.
One thing that attracted me, a graphically challenged developer, to Flex in the first place was that Flex's default UI appearance was already beyond anything I could have ever designed. In addition, Flex components, like their Swing cousins, define UI delegates that make it easy to customize a component's visual presentation. Unlike in Swing, where you can code up and associate a new UI delegate with a component, Flex lets a developer specify some delegate settings via a CSS stylesheet as well. CSS-based component styling brings one of the best features of HTML to Flex developers. Similar functionality for Swing was discussed in the Java community several years ago, but then the JavaFX effort crowded out such desires.
Specifying UI presentation closely relates to each framework's programming model. It is in their programming models that HTML, Swing, Ajax, and Flex differ the most.
HTML can be considered a layout language in the sense that HTML code specifies the positioning of components on the screen. Inasmuch as HTML code works closely with the browser's DOM and rendering engine, it can also be considered a domain-specific language for container-based UI layout. HTML's simple, container-based layout model has proven very effective, and is well-understood by developers.
At the opposite end of the programming model spectrum stands Swing: with Swing, you get the full power and expressivity of the Java language, but not much that would simplify common UI tasks. Even container-based layout, a common UI development chore, is performed in full Java code. JavaFX attempted to address that with a scripting language, but JavaFX was not Swing and did not work well with existing Swing code or components.
Ajax provides the best of the HTML and Swing worlds: HTML is part and parcel of Ajax, but Ajax applications typically take advantage of the browser's JavaScript engine to interact with the DOM, setting styling elements, making network calls, or even completely dynamically building the UI.
Ajax applications, however, are limited by the scalability issues inherent in browser-based JavaScript, as well as by the JavaScript and DOM idiosyncrasies of various browsers. Ajax frameworks, such as YUI, script.aculo.us, JQuery, or GWT attempt to solve some of those issues. But the extent to which those client-side frameworks tie into server-side programming models, client-side application design decisions can leak into the system's architecture. For instance, Rails and JSF both provide outstanding integration with Ajax frameworks, but at the price of the application's architecture having to follow that of Rails or JSF.
Flex retains some of the container-based layout simplicity of HTML with its own layout DSL, MXML. Like HTML, Flex also permits the use of CSS styling techniques. However, instead of JavaScript, Flex combines its layout DSL with ActionScript, which lends higher-level features, such as classes, interfaces, and packages, as well as static typing to the task of coding up interactive aspects of the UI. Because Flex runs inside the Flash Player plugin, it renders as moot any notion of browser-incompatibility on platforms for which the Flash Player is available. Flash Player is also heavily optimized for performance even of graphically rich applications, and benefits from hardware graphics acceleration, when possible.
Flex does not impose any sort of system-wide architecture on a Web application: A Flex component can be embedded into an existing HTML page, progressively enhancing that page, or it can serve as the basis in a page-per-application model where the entire Web is, in effect, the Flex app. A Flex application can interact with its environment in a variety of ways: It can acquire data from its surrounding HTML page via Flash variables, it can communicate HTTP-bound data sources, or it can take directly invoke server-side Java objects via the open-source BlazeDS framework.
BlazeDS, in particular, has proven effective in our application, as it not only takes care of remotely invoking methods on server-side Java objects, it also serializes complex methor parameters and return values, converting between Java and ActionScript objects. That enables a client-side application to benefit from a rich server-side object model common to many business applications.
Flex retains some of the simplicity of HTML with its containment-oriented layout DSL, MXML. Flex employs the ActionScript language on the client, which will be familiar to Java and Swing developers with its optional static typing and classes, and is an improvement over plain old JavaScript. Flex applications run inside a browser or on the desktop; and when they run inside the browser, the Flash Player plugin eliminates browser incompatibility problems. Flex also comes with a rich API and many open-source tools and libraries. Finally, the Eclipse-based FlashBuilder IDE provides several tools useful in an enterprise development setting, such as a debugger, a profiler, and a network monitor allowing for inspection of low-level network communication details.
Flex also seems to be improving with each new release. The latest version, Flex 4, introduced a new component architecture with strong separation of visual and non-visual application elements. That separation directly facilitates closer collaboration between designers and developers, a familiar arrangement for those working with enterprise Web apps.
But Flex has a few minuses, too. The biggest one perhaps is that Flex applications don't run on the iPhone or the iPad, two increasingly popular devices. However, Flex applications do run out of the box on any device with the latest Android release. While ActionScript is an effective language for UI development, ActionScript code does not look as pretty as Ruby, neither is it as expressive as Scala. Some of ActionScript's shortcomings can be traced back to it wanting to be the next-generation JavaScript, slavishly implementing some of the seedier JavaScript features. Although, like Scala, ActionScript is a functional and object-oriented language, unlike Scala, it doesn't fully exploit that combination to the benefit of developer productivity. Perhaps it will evolve in that direction now that it shed its JavaScript ambitions.
Overall, however, I found Flex fun to program in. While Flex is not without shortcomings, it is so far the most desirable solution I found throughout the journey of writing a similar kind of application four times, each time with different UIs.
Flex.org
http://www.flex.org
Flex 4 Fun by Chet Haase
http://www.artima.com/shop/flex_4_fun
Have an opinion? Readers have already posted 26 comments about this article. Why not add yours?
Frank Sommers is Editor-in-Chief of Artima.
Artima provides consulting and training services to help you make the most of Scala, reactive
and functional programming, enterprise systems, big data, and testing.