
package com.smartgwt.client.docs;

/**
 * <h3>Smart GWT Architecture</h3>
 * Smart GWT can add interactivity and performance benefits to any web application with a
 *  variety of integration approaches.  This topic discusses the optimal architecture for a
 *  Smart GWT application, which can be adopted in whole or in part.
 *  <p>
 *  In a typical HTML-based web application, every time a new view is shown to a user, a round
 *  trip to the server is required to retrieve new presentation information, such as a search
 *  screen.  However in an ISC-based application, showing a new view can be accomplished by
 *  simply hiding some components and showing others.
 *  <p>
 *  Because ISC components are expressed in a concise declarative form, and because ISC
 *  components have essentially no runtime performance impact until used, dozens of application
 *  views can be downloaded to the browser using the same bandwidth that would have been
 *  required to render just the initial view in plain HTML.  
 *  <p> 
 *  This architectural pattern of "preloading views" has tremendous benefits.  View transitions
 *  which do not require new data from the server can be performed near-instantaneously and
 *  without server involvement, boosting both interactivity and scalability.
 *  <p>
 *  Showing a dialog containing a "wizard" is a straightforward example of showing a "preloaded
 *  view".  For example:
 *  <pre>
 *     function showNewUserWizard() {
 *         Window.create({
 *             items:[
 *                 DynamicForm.create({ ... })
 *             ]
 *         });
 *     }
 *     Button.create({
 *         title:"New User..",
 *         click:"showNewUserWizard()"
 *     });
 *  </pre>
 *  In this example, none of the components involved in a potentially multi-pane wizard are 
 *  created until they are needed.  Showing the wizard has near-instantaneous response and
 *  causes no server load.
 *  <p>
 *  However, let's say that the first pane of the wizard is going to incorporate some dynamic
 *  user-specific data, such as the current user's name.  To load the username, we'll use an RPC
 *  operation targetting a .jsp called "getUserName.jsp" and show the wizard when it completes
 * (see {@link com.smartgwt.client.rpc.RPCManager} for information on RPCs and how to construct a
 * .jsp that can
 *  send an RPC response).
 *  <pre>
 *     function showNewUserWizard() {
 *         RPCManager.sendRequest({
 *             actionURL:"getUserName.jsp",
 *             callback:"doShow(rpcResponse)"
 *         });
 *     }
 *     function doShow(rpcResponse) {
 *         Window.create({
 *             items:[
 *                 Canvas.create({contents:"Hello, " + rpcResponse.userName}),
 *                 DynamicForm.create({ ... })
 *             ]
 *         });
 *     }
 *     Button.create({
 *         title:"New User..",
 *         click:"showNewUserWizard()"
 *     });
 *  </pre>
 *  In this example, we've simply incorporated a user name into the first pane of a wizard.
 *  However, this pattern allows us to arbitrarily change user interactions based on data from
 *  the server.  For example, the RPCResponse might have contained a flag indicating that the
 *  wizard should skip the first two steps, or an arbitrary warning message for the user, or
 *  even JavaScript code to be evaluated on the client.
 *  <P>
 *  This architecture has several key advantages:
 *  <dl>
 * 
 *  <dt><b>Performance: Cacheable UI</b></dt>
 *  <dd>
 *  A dynamic, data-driven UI can be expressed completely in <i>cacheable</i> JavaScript.
 *  This is in contrast to any architecture based on server-side HTML generation, where static
 *  parts of the presentation are mixed in with dynamic data, preventing cacheability so that
 *  bandwidth and server time are wasted repeatedly delivering the same static presentation
 *  data.
 *  <br>
 *  Even generated JavaScript is cacheable.  For example, a Smart GWT View expressed in XML
 *  and contained within a JSP is still a separately cacheable resource when loaded via a
 *  &lt;SCRIPT SRC&gt; tag and advertised as a cacheable resource via HTTP headers, because it
 *  is ultimately delivered to the browser as simple JavaScript.  Hence standard 
 * {@link com.smartgwt.client.docs.I18n internationalization} techniques such as using JSTL tags
 * in a JSP remain
 *  applicable.
 *  <br>
 *  The Smart GWT Architecture even allows you to capture all the gradations of cacheability
 *  from completely static (changes once per application rollout) to completely dynamic
 *  (timestamp).  In the example above, the user name wouldn't actually change for the lifetime
 *  of the page, so could be loaded once only.
 *  <br>&nbsp;</dd>
 * 
 *  <dt><b>Performance: Minimal Server State</b></dt>
 *  <dd>
 *  Any architecture that relies on component descriptions being generated by the server
 *  must track a great deal of state, which, in the Smart GWT Architecture, is either
 *  completely eliminated or greatly reduced.
 *  <br>&nbsp;</dd>
 * 
 *  <dt><b>True Presentation / Business Logic separation</b></dt>
 *  <dd>
 *  The RPCResponse object represents the client's exact, minimal needs for server data.
 *  This is much easier to understand and to audit than a slew of .jsp files which access and
 *  update miscellaneous state.  It is also far easier to spot reusable patterns of data access,
 *  which in server-side HTML generation systems often end up as duplicated code.
 *  <br>&nbsp;</dd>
 * 
 *  <dt><b>Parallel Development and Testability</b></dt>
 *  <dd>
 *  Using the Smart GWT architecture allows you to build a complete, working application
 *  that can run without a server, based on sample data.  In the example above, it would be 
 *  straightforward to create a testing mode that returned a faked RPC response consisting of
 *  simply <code>{ userName : "Bob" }</code>.
 *  <br>
 *  This allows better parallel development by enabling the client side of the system to be
 *  tested in isolation, and creates clearer communication between client and server-side
 *  developers since creation of test data tends to develop into data requirements
 *  specifications.
 *  <br>
 *  For more info on creating applications that support client-only testing, see
 *  {@link com.smartgwt.client.docs.ClientOnlyDataSources Client Only DataSources}.
 *  <br>&nbsp;</dd>
 *  </dl>
 *  <br>
 *  <h3>Refinements</h3>
 *  <br>
 *  <b>Creating vs Showing a View</b>
 *  <br>
 *  Many views will be shown to the user repeatedly, for example, the user may repeatedly switch
 *  back and forth between two panes of a TabSet.  In that usage it makes sense to make a
 *  distinction between <i>creating</i> a view and <i>showing</i> an existing view.  When
 *  showing an existing view, the same components and/or data may be able to be reused.
 *  <br>
 *  In the following variant on the original example, we only create the Window object and
 *  do the RPC to retrieve the user name the first time <code>showNewUserWizard()</code> is
 *  called.  Subsequently we reuse the existing window, and we assume the user name has not
 *  changed, so we need not do the RPC again. (<i>Note: "New User" button omitted for brevity
 *  from here on</i>)
 *  <pre>
 *     function showNewUserWizard() {
 *         if (!window.myWindow) {
 *             Window.create({
 *                 ID:"myWindow",
 *                 autoDraw:false,
 *                 items:[
 *                     Canvas.create({ ID: "welcomeCanvas" }),
 *                     DynamicForm.create({ ... })
 *                 ]
 *             });
 *             RPCManager.sendRequest({
 *                 actionURL:"getUserName.jsp",
 *                 callback:"doShow(rpcResponse)"
 *             });
 *         } else {
 *             myWindow.show();
 *         }
 *     }
 *     function doShow(rpcResponse) {
 *         welcomeCanvas.setContents("Hello, " + rpcResponse.userName);
 *         myWindow.show();
 *     }
 *  </pre>
 *  
 *  <b>Batching Operations</b>
 *  <br>
 *  A view may incorporate multiple components, each of which requires data.  In the following
 *  example, a DataBound ListGrid has been incorporated into the wizard, and we'd like to fetch
 *  the user's name and the beginning dataset for the grid in the same batch.  We use 
 *  {@link com.smartgwt.client.rpc.RPCManager#startQueue RPCManager.startQueue()} to do so.
 *  <pre>
 *     function showNewUserWizard() {
 *         if (!window.myWindow) {
 *             Window.create({
 *                 ID:"myWindow",
 *                 autoDraw:false,
 *                 items:[
 *                     Canvas.create({ ID: "welcomeCanvas" }),
 *                     <b>ListGrid.create({ 
 *                         ID: "myGrid",
 *                         dataSource:"myDataSource"
 *                     }),</b>
 *                     DynamicForm.create({ ... })
 *                 ]
 *             });
 *             <b>RPCManager.startQueue();
 *             myGrid.fetchData();</b>
 *             RPCManager.sendRequest({
 *                 actionURL:"getUserName.jsp",
 *                 callback:"doShow(rpcResponse)"
 *             });
 *             <b>RPCManager.sendQueue();</b>
 *         } else {
 *             myWindow.show();
 *         }
 *     }
 *     function doShow(rpcResponse) {
 *         welcomeCanvas.setContents("Hello, " + rpcResponse.userName);
 *         myWindow.show();
 *     }
 *  </pre>
 * 
 *  <b>Segmenting very large Applications</b>
 *  <P>
 *  If an application has many hundreds of views, but only a handful of views are used by a
 *  given user in a typical session, for the fastest loading performance you should consider
 *  loading only the most commonly used views initially then loading further views on demand.
 *  <P>
 *  You can use  FileLoader.loadJSFiles() to load a set of JavaScript files
 *  compromising an application module that defines a set of related views.  The loaded
 *  JavaScript files may define new component classes and new DataSources in addition to
 *  defining new views and their associated logic.
 */
public interface SmartArchitecture {
}
