Section 13.5. Fat Client


13.5. Fat Client

BrowserSide, Decoupled, DHTML, Fast, Responsive, Rich, Thick

Figure 13-11. Fat Client


13.5.1. Developer Story

Dave's new mortgage application is very quick as it avoids server calls wherever possible. After some benchmarking, he discovered that optimized JavaScript is actually fast enough to run the financial algorithms in the browser, so that users now receive almost immediate feedback as they tweak parameters.

13.5.2. Problem

How can you architect the system to feel truly rich and interactive?

13.5.3. Forces

  • The application should respond to user actions quicklyideally, instantaneously.

  • Responses from the server can be noticeably latent due to data transfer and server processing overheads.

13.5.4. Solution

Create a responsive Ajax App by performing remote calls only when there is no way to achieve the same effect in the browser. Whereas the server is traditionally the realm of more complex processing, this pattern suggests harnessing the browser for all it's worth. In the extreme case, it means running just about everything inside the browser, but that's not the main message here. The main message is to reconsider the traditional server-centric view of web architecture; for developers to be more conscious about decisions on matters regarding where the various components live. Placing more logic inside the browser gives you the opportunity to make the application more responsive.

Web apps usually have several layers:

  • User interface

  • Application logic

  • Business logic

  • Data access

  • External system communication

The user interface is what the user sees and interacts with. The application logic concerns the dialogue between the user and the computer, the flow of information back and forthfor example, given a particular user action, what should the computer do next? The business logic concerns knowledge about the domain and the web site owner's practices and policies. The data access layer concerns reading and writing data to a persistent store. External system communication is also necessary in many enterprise systems, where outside systems play the role of information sources and sinks.

Conventional web apps concentrate UI code in the browser, using a mix of HTML and CSS, with some JavaScript used to perform a few basic UI tricks like placing keyboard focus or showing some animation or offering a dynamic menu. Everything else is usually managed on the server. This pattern reconsiders the balance by suggesting that some applications are better served pushing application and business logic into the browser (Figure 13-12).

Figure 13-12. Responsibilities of a Fat Client


With application logic in the browser, an inversion of control occurs in which the browser now controls the flow of activity. When the user performs some action, it is the browser that decides how to respond, and it calls the server only if necessary, and for very specific services.

The advice to hold business logic in the browser is anathema to most literature on serious web site development and should not be taken lightly. Business logic in the browser has numerous problems:

  • Programming in JavaScript can be difficult because many features familiar to mainstream developers are unavailable. The standard API is minimal and object-oriented facilities are based on prototypes rather than classes. Indeed, the usage of dynamic typing is also uncomfortable for many developers in the Java and C# camps.

  • Portability is a further complication due to the number of platforms that must be supported, and their subtly inconsistent behaviors.

  • Development is also a challenge. Coding, refactoring, debugging, automated testing, and monitoring, are standard in modern IDEs like IntelliJ Idea, but support at this level is minimal for JavaScript.

  • Security is another constraint that forces logic server side. Savvy users can peruse code and data in the browser and can even tamper with what's sent back to the server. Obfuscationmaking the code difficult to readis a very weak defense.

  • Business and application logic should be held on the server, where they can be reused by other clients.

  • Web data generally can't be saved on the local machine.

Are any of these showstoppers? Let's look at how we can cope with each of these problems:

  • JavaScript may be different from server-side languages, but many programmers are discovering it's a lot more powerful than previously assumed (http://www.crockford.com/javascript/javascript.html). Until recently, the main resources on JavaScript were "cut-and-paste this code" web sites, but there are an increasing number of books and resources that take the language seriously. The language has undergone a renaissance in parallel with Ajax. New idioms and patterns are emerging, along with a pile of cross-browser frameworks to augment the relatively bare native API. The recent introduction of JSAN (http://openjsan.org)a repository of JavaScript libraries like Perl's CPANwill only further reuse. Object-oriented concepts, including inheritance and aggregation, are indeed possible, if not in a manner familiar to all server-side developers. Dynamic versus static typing is a matter of taste that shouldn't affect a language's credibility; the dynamic approach of JavaScript may not be everyone's preference, but JavaScript is hardly an outsider here.

  • Browsers are more standard nowadays, and many of the new libraries abstract away browser dependencies (see Cross-Browser Component [Chapter 12]). For example, over a dozen libraries offer a browser-independent factory method to retrieve XMLHttpRequest.

  • Recent tools are making life a lot easier; some are discussed in Development Patterns (Part V).

  • Security remains an issue, but it's possible to deploy the application so that security- critical functionality can be exposed server side in well-defined services, with the bulk of the application logic held locally and calling on those services as required. There might be duplication because browser-side validation is also important for quick feedback, using JavaScript to create a screening test before passing a request to the server. However, there are ways to deal with such duplication if it's a serious issue. For instance, with server-side JavaScript, you can have the same script running in the browser and the server, or you can use some custom, declarative notation to capture business rules and have processors for it on both sides.

  • It's true that certain business logic needs to be made available to multiple clients and therefore needs to exposed as Web Services, in which case there's a good argument for keeping it inside the server. (It could also be executed in the server as well as the browser, though that's a fairly unusual practice.) Often, though, business logic is application-specific, and that's even more the case for application logic (notwithstanding grandiose plans for running the same app on mobile phones and desktops).

  • Browsers cannot normally persist data locally, but a background thread can be used to periodically synchronize with the server. In the 1990s, many desktop applications forced users to explicitly save their work, whereas today, many desktop applications now save periodically and upon the user quitting. In the same way, it's now feasible for web apps to persist data transparently, without affecting workflow. If local persistence is critical enough to break away from "pure Ajax," some easily deployed Flash libraries are available (e.g., Brad Neuberg's AMASS; see http://codinginparadise.org/projects/storage/README.html).

None of this says that programming in JavaScript is more productive than programming in Java or C# or Ruby. In most cases, it isn't and never will be. Serious JavaScript programming is nonetheless a very real proposition. Professional software development involves choosing the language that fits the task at hand. Given the many benefits of browser-side coding, there are at least some circumstances that make JavaScript the language of choice for implementation of business and application logic.

13.5.5. Decisions

13.5.5.1. How will business and application logic be implemented in the browser?

Conventional applications use JavaScript for a little decoration. Even when a lot of JavaScript is used, it's often packed into tightly scoped library routines, to perform little tricks like validating a form's fields match regular expressions or popping up a calendar. These are just little detours on the well-travelled road between browser and server. In contrast, a Fat Client responds to many events itself, delegating to the server only if and when it deems necessary.

All this implies a very different usage of JavaScript, and there are some techniques that can help. It's beyond the scope of this chapter to cover them in detail, but here are a few pointers:

  • It's easy to fall into the trap of "paving the cow paths"[*] by applying design styles from other languages to JavaScript. It's usually more productive to embrace JavaScript as a unique language with its own idiosyncratic features and usage patterns, and to be wary of applying architectural concepts from your favorite server-side language if they don't seem to fit in.

    [*] "Paving the cow paths" refers to the way cows mindlessly follow an old path, continuing to walk around trees that aren't actually there anymore.

  • JavaScript uses a prototype-based paradigm, which is worth learning about. Object-oriented concepts like inheritance are certainly possible, but it's important to appreciate how they fit in to the prototype model.

  • Development and deployment practices apply as much to a rich browser application, and are as important as testing the server code, as discussed in Development Patterns (Part V).

  • JavaScript runs slower than equivalent desktop applications, so optimization is important. Also, consider issues memory usage and be aware of browser-specific bugs that might lead to memory leaks.

  • Break complex applications into multiple JavaScript files and consider managing them with On-Demand JavaScript.

  • Reuse, Reuse, Reuse. As Appendix A shows, there's a proliferation of JavaScript frameworks and libraries becoming available.

13.5.6. Real-World Examples

13.5.6.1. NumSum

NumSum (http://numsum.com) is an Ajax spreadsheet that provides all the basic spreadsheet functionality in JavaScript: insertion and deletion of rows and columns; various formulas; the ability of a user to enter values into any cell; text-formatting (bold, italic, or underlining); text-justification; and embedded links and images.

The basic spreadsheet is implemented as a table. Table cells aren't actually editable, so the script needs to simulate an editable table. An event handler ensures that a cell becomes active when the user clicks on it, and that cell is then morphed to reflect subsequent user input.

13.5.6.2. Gmail

Gmail (http://gmail.com), like several of its competitors, presents a rich, Ajax interface to a mail system. Conventional web mail offerings rely heavily on form submissions and page reloadsa new page must be opened each time the user wants to start composing an email, finish composing an email, or open up an email message. With Gmail, the list of emails is always present and regularly refreshed. Partial edits are periodically saved as well. All of these activities are handled within the browser using a combination of Display Manipulation (Chapter 5) and Web Remoting (Chapter 6).

13.5.6.3. DHTML Lemmings

DHTML Lemmings (http://www.oldgames.dk/freeflashgames/arcadegames/playlemmings.php) shows how much can be achieved with some clever JavaScript hacking (Figure 13-13). It's a full-featured implementation of the Lemmings PC game utilizing a Richer Plugin only for soundthe entire game runs on DHTML, DOM, and CSS. The gameplay consists of a static image for the current level, with Sprites used to render the lemmings and other objects in the game. There is a periodic timer continuously checking the current state of each object, and DOM manipulation of the objects' properties is used to render their states at any time.

Figure 13-13. DHTML Lemmings


13.5.6.4. JS/UIX shell

JS/UIX shell (http://www.masswerk.at/jsuix/) is a demo of an in-browser Unix shell (Figure 13-14). In its current form, it's a demo only. But it's capable of all the basic operating systems commands and even includes a vi editor! The approach stands in contrast to browser-side terminal emulators, which are thin applications that pass characters back and forth. With appropriate server-side integration, the application could be made into a functional multiuser application. Command line remains the mode of choice for many power users, and this demo shows how an Ajax Fat Client can achieve it.

Figure 13-14. JS/UIX shell


13.5.7. Code Example: AjaxPatterns Basic Wiki

The Wiki Demo (http://ajaxify.com/run/wiki) is based on Fat Client principles, though its functionality is fairly limited. All of the interaction and rendering occurs locally. The only interaction with the server is a periodic synchronization event, when the following occurs:

  • Pending messages are uploaded, an example of Submission Throttling (Chapter 10).

  • All current messages are retrieved from the server, so that messages from other users are shown. This is an example of Periodic Refresh (Chapter 10).

There's a timer to ensure synchronization occurs after five seconds of inactivity:

   var syncTimer = null;   function startPeriodicSync( ) {     stopPeriodicSync( );     syncTimer = setInterval(synchronise, 5000);   }   function stopPeriodicSync( ) {     clearInterval(syncTimer);   } 

The timer starts on page load and is suspended each time the user begins to modify some text:

   window.onload = function( ) {     synchronise( );     startPeriodicSync( );   }   function onMessageFocus(event) {     ...     stopPeriodicSync( );   }   function onMessageBlur(event) {     ...     startPeriodicSync( );   } 

The script also contains a variable to accumulate pending messages whenever the user changes something:

   var pendingMessages = new Array( );   ...   function onMessageBlur(event) {   ...     if (message.value != initialMessageContent) {       pendingMessages[message.id] = true;     ...   } 

The synchronization event builds up some XML to post to the server, based on the pendingMessages array that has been accumulated. If no changes are pending, it simply requests the current server state. If there are changes pending, it posts those changes as an XML message. Either way, the server will respond with an XML specification of its current state.

   function synchronise( ) {     var messageTags = "";     for (messageId in pendingMessages) {       var initialServerMessage = $(messageId).serverMessage;       messageTags += "<message>";       messageTags += "<id>" + messageId + "</id>";       messageTags += "<lastAuthor>" + $("authorIdSpec").value + "</lastAuthor>";       messageTags += "<ranking>" + initialServerMessage.ranking + "</ranking>";       messageTags += "<content>" + escape($(messageId).value) + "</content>";       messageTags += "</message>";       $(messageId).style.backgroundColor = "#cccccc";     }     var changesOccurred = (messageTags!="");     if (!changesOccurred) {       ajaxCaller.getXML("content.php?messages", onMessagesLoaded);       return;     }     var changeSpec = "<messages>" + messageTags + "</messages>";     ajaxCaller.postBody       ("content.php", null, onMessagesLoaded, true, null, "text/xml", changeSpec);     pendingMessages = new Array( );   } 

The main application logic is virtually orthogonal to server synchronization. The only concession is the accumulation of pending messages, to save uploading the entire browser state each time. The timer and the synchronization process know about the core wiki logic, but the core wiki knows nothing about them and can therefore be developed independently. It's easy to imagine how the wiki could evolve into something with much richer browser-side features, like formatted text and draggable messages and so on.

13.5.8. Alternatives

13.5.8.1. Thin client

A thin client contains only basic JavaScript and frequently refers back to the server for user interaction. This is likely to remain the dominant style for Ajax Apps and is useful in the following circumstances:

  • It's important to support legacy browsers. Graceful degradation is still possible with Fat Clients, but requires more work, and there's the potential for a lot of redundancy.

  • Business logic requires sophisticated programming techniques and libraries that can only be implemented server side.

  • Business logic involves substantial number crunching or other processing that can only be performed server side.

  • Due to bandwidth and memory constraints, the application cannot be held locally.

  • There is complex dialogue required with external services, and due to cross-domain security policies, those services cannot be accessed from the browser.

13.5.8.2. Desktop client

A desktop client runs as a standard application in the user's operating system, and connects to one or more servers using HTTP or any other protocol. Compared to a Fat Client, a desktop client can be richer and faster. However, the benefits of a web-enabled application are lost as a result. You can compensate for some of these benefits:

  • Portability can be achieved with a platform-neutral programming platform.

  • Centralized data can be achieved by ensuring all data is retained server side.

  • Familiar user interfaces can be achieved by tailoring to each individual platform's look-and-feel.

In some contexts, a desktop client represents the best of both worlds: a rich client backed by a powerful server. In other situations, a Fat Client based on Ajax principles is a more appropriate sweet spot: a powerful server, a rich-enough client, and easy access through any modern web browser.

13.5.9. Related Patterns

13.5.9.1. Periodic Refresh

Periodic Refresh (Chapter 10) is a relatively unobtrusive way for the client state to be enriched with any new server-side information.

13.5.9.2. Submission Throttling

Submission Throttling (Chapter 10) is a relatively unobtrusive way for the server to be notified of any significant changes that have occurred in the browser.

13.5.9.3. Widgets

If the user is going to spend a long time in the browser, the various widgets (Chapter 14) should be adopted to improve the experience.

13.5.9.4. On-Demand JavaScript

Since Fat Clients tend to contain bulkier scripts, On-Demand JavaScript (Chapter 6) is useful for managing them.

13.5.9.5. Drag-And-Drop

Drag-And-Drop (Chapter 15) is familiar to many desktop users and helps to make a large application feel more natural. Whereas more conventional web clients rely on form-style interaction, Fat Clients can feel more rich if they support Drag-And-Drop.

13.5.9.6. Host-Proof Hosting

Where a Fat Client is seen as a replacement for a desktop equivalent, Host-Proof Hosting (Chapter 17) might be considered to avoid compromising on the superior security a localized solution sometimes offers.

13.5.10. Metaphor

Agile development methodologies such as Scrum aim for an "inversion-of-control." Workers (like the Fat Client) are empowered to plan their own activities, and management's role (the Server) is to offer whatever services workers request in order to conduct those activities.

13.5.11. Want to Know More?

  • Google Groups Discussion: "Applications in the Browser or the Server?" (http://groups-beta.google.com/group/ajax-web-technology/browse_thread/thread/e40317a830ad841d/06483bf77587a62c#06483bf77587a62c)

  • "JavaScript: The World's Most Misunderstood Programming Language" by Douglas Crockford (http://www.crockford.com/javascript/javascript.html)

  • "JavaScript is not the devil's plaything" by Cameron Adams (http://www.themaninblue.com/writing/perspective/2005/04/12/)




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net