<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEAMRHwzfCp7ImA9WhRbEEg.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505</id><updated>2012-01-31T15:33:05.284-08:00</updated><title>Sign of the times</title><subtitle type="html">Technical Articles by Sony Mathew, Software Architect, Twin Cities, MN</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://sonymathew.blogspot.com/" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/SignOfTheTimes" /><feedburner:info uri="signofthetimes" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CEAMRH06eCp7ImA9WhRbEEg.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-2244694790687414616</id><published>2012-01-30T16:40:00.000-08:00</published><updated>2012-01-31T15:33:05.310-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T15:33:05.310-08:00</app:edited><title>State Driven Design (SDD)</title><content type="html">&lt;html&gt;&lt;head&gt;&lt;title&gt;State Driven Design&lt;/title&gt;&lt;style type="text/css"&gt;@import url('https://themes.googleusercontent.com/fonts/css?kit=lhDjYqiy3mZ0x6ROQEUoUw');ol{margin:0;padding:0}p{margin:0}.c6{max-width:468pt;background-color:#ffffff;padding:72pt 72pt 72pt 72pt}.c4{font-size:10pt;font-family:Consolas}.c0{font-size:9pt;font-family:Consolas}.c3{font-size:12pt}.c5{text-decoration:underline}.c1{direction:ltr}.c7{font-family:Consolas}.c2{height:11pt}.title{padding-top:24pt;color:#000000;font-size:36pt;font-family:Arial;font-weight:bold;padding-bottom:6pt}.subtitle{padding-top:18pt;color:#666666;font-style:italic;font-size:24pt;font-family:Georgia;padding-bottom:4pt}body{color:#000000;font-size:11pt;font-family:Arial}h1{padding-top:24pt;color:#000000;font-size:24pt;font-family:Arial;font-weight:bold;padding-bottom:6pt}h2{padding-top:18pt;color:#000000;font-size:18pt;font-family:Arial;font-weight:bold;padding-bottom:4pt}h3{padding-top:14pt;color:#000000;font-size:14pt;font-family:Arial;font-weight:bold;padding-bottom:4pt}h4{padding-top:12pt;color:#000000;font-size:12pt;font-family:Arial;font-weight:bold;padding-bottom:2pt}h5{padding-top:11pt;color:#000000;font-size:11pt;font-family:Arial;font-weight:bold;padding-bottom:2pt}h6{padding-top:10pt;color:#000000;font-size:10pt;font-family:Arial;font-weight:bold;padding-bottom:2pt}&lt;/style&gt;&lt;/head&gt;&lt;body class="c6"&gt;
&lt;p class="c1 c2"&gt;&lt;span class="c3"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Object-Oriented &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;esign &lt;/span&gt;&lt;span class="c0"&gt;has been&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;a powerful problem solving &lt;/span&gt;&lt;span class="c0"&gt;paradigm for many years now and it still continues to be a force, but as practiced&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="c0"&gt;traditionally it has also been&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;limited in many ways. Any Architecture &lt;/span&gt;&lt;span class="c0"&gt;attempting&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;to distribute objects across &lt;/span&gt;&lt;span class="c0"&gt;multiple&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="c0"&gt;nodes&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;and &lt;/span&gt;&lt;span class="c0"&gt;processes while still trying to maintain object semantics soon encounters a &lt;/span&gt;&lt;span class="c0"&gt;scalability &lt;/span&gt;&lt;span class="c0"&gt;nightmare&lt;/span&gt;&lt;span class="c0"&gt;.&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="c0"&gt;The reasons for these &lt;/span&gt;&lt;span class="c0"&gt;limitations &lt;/span&gt;&lt;span class="c0"&gt;are&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;a lack of constraints on object design around encapsulation and composition&lt;/span&gt;&lt;span class="c0"&gt;. Traditional &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;omain &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;riven &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;esign builds on &lt;/span&gt;&lt;span class="c0"&gt;the p&lt;/span&gt;&lt;span class="c0"&gt;rinciples of &lt;/span&gt;&lt;span class="c0"&gt;O&lt;/span&gt;&lt;span class="c0"&gt;bject-&lt;/span&gt;&lt;span class="c0"&gt;O&lt;/span&gt;&lt;span class="c0"&gt;riented &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;esign and inherits &lt;/span&gt;&lt;span class="c0"&gt;some of these&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;same limitations.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c7"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Traditional &lt;/span&gt;&lt;span class="c0"&gt;O&lt;/span&gt;&lt;span class="c0"&gt;bject-&lt;/span&gt;&lt;span class="c0"&gt;O&lt;/span&gt;&lt;span class="c0"&gt;riented &lt;/span&gt;&lt;span class="c0"&gt;D&lt;/span&gt;&lt;span class="c0"&gt;esign principles work best when confined to the boundary of the local application context. Objects like String&lt;/span&gt;&lt;span class="c0"&gt;,&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;Number, Lists&lt;/span&gt;&lt;span class="c0"&gt;,&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;Maps&lt;/span&gt;&lt;span class="c0"&gt;, &lt;/span&gt;&lt;span class="c0"&gt;Tree&lt;/span&gt;&lt;span class="c0"&gt;s&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;and Graphics are represented &lt;/span&gt;&lt;span class="c0"&gt;well as &lt;/span&gt;&lt;span class="c0"&gt;fully encapsulated objects for consumption within a local application context. These objects are not meant to be distr&lt;/span&gt;&lt;span class="c0"&gt;i&lt;/span&gt;&lt;span class="c0"&gt;buted and scaled beyond one application &lt;/span&gt;&lt;span class="c0"&gt;process or even &lt;/span&gt;&lt;span class="c0"&gt;one user at a time in some cases. &lt;/span&gt;&lt;span class="c0"&gt;S&lt;/span&gt;&lt;span class="c0"&gt;calability across many servers spanning many concurrent users requires a different design paradigm&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;altogether.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;S&lt;/span&gt;&lt;span class="c0"&gt;calable object design can be achieved &lt;/span&gt;&lt;span class="c0"&gt;by &lt;/span&gt;&lt;span class="c0"&gt;softening some of these traditional object design &lt;/span&gt;&lt;span class="c0"&gt;constraints that impair scalability &lt;/span&gt;&lt;span class="c0"&gt;and &lt;/span&gt;&lt;span class="c0"&gt;replacing them with &lt;/span&gt;&lt;span class="c0"&gt;new constraints &lt;/span&gt;&lt;span class="c0"&gt;that&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;harden scalability. We can achieve this in part by applying the constraints of REST atop a loose form of object design&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;-&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;REST &lt;/span&gt;&lt;span class="c0"&gt;being a &lt;/span&gt;&lt;span class="c0"&gt;proven scalable architecture of the World Wide Web. &lt;/span&gt;&lt;span class="c0"&gt;I&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;call this design approach &lt;/span&gt;&lt;span class="c0 c5"&gt;State Driven Design&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;(SDD).&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Let us start with &lt;/span&gt;&lt;span class="c0"&gt;some&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;traditional object design and apply a few &lt;/span&gt;&lt;span class="c0"&gt;of these key &lt;/span&gt;&lt;span class="c0"&gt;constraints to see where we end up. &lt;/span&gt;&lt;span class="c0"&gt;We&amp;#39;ll&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;start with a truly old school object design around an Account. &amp;nbsp;We don&amp;rsquo;t see this type of traditional design much in practice any more due to its impracticality.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;
&lt;a href="http://1.bp.blogspot.com/-rhKeHT0-u6g/Tyh3hVf95rI/AAAAAAAAAlY/3vMr4NX9OOE/s1600/image01.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width:585px; height: 632px;" src="http://1.bp.blogspot.com/-rhKeHT0-u6g/Tyh3hVf95rI/AAAAAAAAAlY/3vMr4NX9OOE/s1600/image01.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5703940342655346354" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.q5zs79a6zxyi"&gt;&lt;/a&gt;&lt;span&gt;[Constraint] Separate Caller-Visible State&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Applying this first constraint requires that all state a caller of an operation may inspect or modify should be separated into its own state object, while all operations that fulfill the needs of the caller be separated into a service. Caller-visible state is state which the caller must see, understand, and modify to interact with the system correctly. Its important to make a distinction between caller-visible state and internal implementation-specific state which the services still encapsulate and is of no interest to the caller. &lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Applying this constraint:&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;
&lt;a href="http://4.bp.blogspot.com/-53F1hkb8BLo/Tyh1PwqWNdI/AAAAAAAAAlM/EgaNNOFIrMY/s1600/image00.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 800px; height:400px;" src="http://4.bp.blogspot.com/-53F1hkb8BLo/Tyh1PwqWNdI/AAAAAAAAAlM/EgaNNOFIrMY/s1600/image00.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5703937841685738962" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;State objects should be lightweight, transportable and reconstitutable across the network if necessary without changing its value. Operations that formerly acted on caller-visible properties get separated into service objects that are now parametrized with state objects when necessary. Once a caller obtains a state object from the service, the caller should be able to inspect or modify the state independent of the service, additionally the caller must be able to construct a state object independent of the service.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Callers of operations are naturally other operations that should also be refactored in the same fashion, reverse-recurse outward until reaching the outermost operations acting on behalf of the external actor(s).&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.qa0wycfikxe9"&gt;&lt;/a&gt;&lt;span&gt;[Constraint] Caller-neutral Services&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Services should not be caller-specific, they should be caller-neutral and be accessible to any number of concurrent callers, conversely a caller should be able to call any instance of a specific type of service at anytime. If caller-visible state has been externalized as dictated by the previous constraint then it can now be provided to the service as parameters instead of the service maintaining state on behalf of a specific caller. In the case of the AccountService example, it now expects an Account as a parameter and no longer assumes a specific Account or Customer.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;This caller-neutral nature of a service is an important scalability measure. Services can now be replicated across nodes as necessary to accommodate varying caller loads.&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.f1cjsedp4dd3"&gt;&lt;/a&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Constraint] Uniform Service Operations&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;We have already achieved a reasonable amount of scalability with just the previous constraints and could stop there. The Uniform Service Operations constraint takes it a step further and provides the framework for cross-cutting concerns such as security, and improved scalability through proxies and caches and in general the ability to nest and chain services to separate concerns.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;This constraint requires that all services conform to a uniform set of operations. This is generally accomplished in two parts, first generalize the methods to the universal set of operations, then generalize the parameters and return values to a basic request-response model. Operations that no longer fit the service need to be organized into new states and services as shown in the example.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Applying constraints thus far (and others not yet described):&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;
&lt;a href="http://3.bp.blogspot.com/-Fsa_hdqeBH0/Tyh4LA18NnI/AAAAAAAAAlk/9JmUs6qt7nk/s1600/image02.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 800px; height: 800px;" src=http://3.bp.blogspot.com/-Fsa_hdqeBH0/Tyh4LA18NnI/AAAAAAAAAlk/9JmUs6qt7nk/s1600/image02.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5703941058664871538" /&gt;&lt;/a&gt;
&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;As you can see, AccountService offers a generalized set of operations which for simplicity&amp;#39;s sake were kept to just the basic CRUD operations (create, read, update, delete) but this set can be be expanded to include other types of generalized operations. Also notice as a consequence, use-cases such as withdraw, deposit, and transfer no longer fit and needed to be refactored out to new states and accompanying services.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;These generalized operations can now be monitored, proxied and secured in a generalized way e.g. an actor might be able to read AccountTransactions within the system but not update or delete them. Additionally, a generalized request-response model allows for states to be cached for requests that allow as such.&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.9ryovegdaj4x"&gt;&lt;/a&gt;&lt;span&gt;[Constraint] Hold References by ID&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;If a state object has an accompanying service to manage it then objects should reference this state by its ID and retrieve the state as needed on demand via the service rather than maintaining long-lived object references to the state object. These IDs can be database IDs or other forms of persistence IDs, or they could be UUIDs or GUIDs, or they could even just be plain timestamps or process scoped IDs for short-lived non-persistent state objects. Dependent state objects that don&amp;#39;t require services to manage them may be embedded directly within their parent states as object references to form aggregates and managed by the aggregates&amp;#39; services.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;This constraint goes a long way towards facilitating distribution and replication of services across many nodes. It allows state to be retrieved on demand in the most efficient and scalable way, be it remote retrieval or a local cache look-up.&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.p5ivv8bkuoy1"&gt;&lt;/a&gt;&lt;span&gt;[Concern] Business Logic&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;In all this CRUD one may be confused as to where Business logic would live. They live in the CRUD operations of course! Each state object represents a domain concept and its accompanying service represents how that domain will be managed and processed, hence it must also execute the business rules associated with this specific domain. &lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;For example business rules associated with transferring funds would reside in the update operation of the AccountTransferService since the AccountTransfer state represents the domain around the transfer use-case. These rules may further be distributed across finer services that manage finer aspects of this domain, for example AccountTransferService will likely call on the AccountTransactionService to apply withdraw and deposit transaction rules who in turn will likely call the AccountService to apply the rules around updating an Account.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Additionally, uniform service operations allows for separating concerns by decorating and nesting services of the same type. For example, one could have 2 implementations of an AccountTransferService nested within each other, where one is solely responsible for business rules around transfers while the other solely responsible for its persistence. This nesting would be encapsulated from the caller.&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.wfj8a3g4akel"&gt;&lt;/a&gt;&lt;span&gt;[Concern] I/O optimization&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;You can choose to decompose state objects into finer and finer states each with their own services to manage them, where the outermost state and its accompanying service might represent a top-level use-case while the smallest state and service might be handling the persistence of a line-item. Now such a fine decomposition may &lt;/span&gt;&lt;span class="c0 c5"&gt;not&lt;/span&gt;&lt;span class="c0"&gt;&amp;nbsp;be optimal for persistence or other I/O concerns depending on your system, and batching or coarse-grained I/O operations may be required, If this is the case you should embed the fine-grained state objects directly as object references into their parent states to form coarse-grained aggregates and scrap the fine-grained services altogether, then optimize I/O directly within the aggregates&amp;#39; services managing aggregate states with batched I/O operations.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Additional I/O concerns may also exist around searches and bulk updates. Though not shown here explicitly, one could extend the universal operations of CRUD with overloaded variations of read and update to accommodate search and bulk updates. For example one could add operations like read(AccountFilter) or update(AccountFilter).&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.n9oc1h6dhf12"&gt;&lt;/a&gt;&lt;span&gt;[Conclusion] Applying State Driven Design&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;For a given actor and use-case the designer of a State Driven Design (SDD) model looks to capture the state the actor would be interested in examining prior to execution of the use-case followed by the capture of the transformed state after execution of the use-case. It is important to capture the pre and post states of the use-case execution purely from the perspective of the actor who will examine these states.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Next create a CRUD service to manage this state. How this service manages or transforms this state internally should be encapsulated from the actor who only cares about the final state that represents the completion of the use-case. Now, apply this rule recursively, the newly created service now becomes the new actor (or caller) requiring the use of finer-grained states and services.&lt;/span&gt;&lt;/p&gt;&lt;p class="c1 c2"&gt;&lt;span class="c0"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;In essence, SDD is about modeling states and their transformations by the System.&lt;/span&gt;&lt;/p&gt;&lt;h3 class="c1"&gt;&lt;a name="h.qw5wglge90xi"&gt;&lt;/a&gt;&lt;span&gt;[Conclusion] Applying Object-Oriented Design&lt;/span&gt;&lt;/h3&gt;&lt;p class="c1"&gt;&lt;span class="c0"&gt;Finally, apply traditional Object Oriented Design rules of generalization and composition to state and service objects independently to eliminate repetition of properties and operations respectively. Pull-up interfaces and abstract base-classes to generalize commonality between states and between services. Decompose complex states and services into finer-grained states and services then manage dependencies between services through Inversion of Control (IoC). As a final note, once in a while when the problem dictates as such, don&amp;#39;t be shy about creating fully encapsulated old-school objects for local application consumption ;-)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-2244694790687414616?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/usR_jJwIfKXtN2hd-D0KXXb11rg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/usR_jJwIfKXtN2hd-D0KXXb11rg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/usR_jJwIfKXtN2hd-D0KXXb11rg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/usR_jJwIfKXtN2hd-D0KXXb11rg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/3ENyYeNlUkI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/2244694790687414616/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=2244694790687414616" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2244694790687414616?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2244694790687414616?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/3ENyYeNlUkI/state-driven-design-sdd.html" title="State Driven Design (SDD)" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-rhKeHT0-u6g/Tyh3hVf95rI/AAAAAAAAAlY/3vMr4NX9OOE/s72-c/image01.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2012/01/state-driven-design-sdd.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AGQ3k_fyp7ImA9WxFRE0Q.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-2389448494284684982</id><published>2010-04-27T13:17:00.001-07:00</published><updated>2010-04-27T13:22:02.747-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-27T13:22:02.747-07:00</app:edited><title>Checked vs. Runtime Exception</title><content type="html">&lt;p&gt; This age old argument has been raised again by many recently and like them I decided to stamp my opinion out on the blog-o-sphere as well. I picked up where &lt;a href="http://beust.com/weblog/2010/04/25/improving-exceptions/" id="wg9l" title="Cedric Beust"&gt;Cedric Beust&lt;/a&gt; left off. &lt;/p&gt;&lt;p&gt; I used to be a proponent of checked exceptions and had strongly stood my ground for a long time but I am now older and more forgiving. Whether an exception is recoverable or Not is mostly contextual. One call path may decide to recover while another may decide to fail from the same exception just as they might decide independent courses of action based on a return value. &amp;nbsp;An exception should only be a vehicle for information and abstracted as such (which is why I think interfaces for exceptions should have existed) while allowing callers under different contextual paths to process the exception as they choose best. &lt;/p&gt;&lt;p&gt;Additionally, many classes are implementations of one or more interfaces. We don&amp;#39;t always have control over interfaces we implement and even when we do we should treat them as immutable as much as possible - mostly because interfaces exist to adapt various implementations to a general contract. When conforming an implementation to one or more general contracts - checked exceptions just cannot be declared consistently and in most cases not even possible. Given this and and the contextual nature of exceptions - it follows naturally that we only need the RuntimeException - however the traditional meaning of the RuntimeException will no longer be valid under this new paradigm - instead it gets redefined as merely a vehicle for Alternate information. &lt;/p&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-2389448494284684982?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J1XWNG6T7uVV1xaElwpB1gzQ4l8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J1XWNG6T7uVV1xaElwpB1gzQ4l8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J1XWNG6T7uVV1xaElwpB1gzQ4l8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J1XWNG6T7uVV1xaElwpB1gzQ4l8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/HeFNCK9xUE0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/2389448494284684982/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=2389448494284684982" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2389448494284684982?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2389448494284684982?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/HeFNCK9xUE0/checked-vs-runtime-exception.html" title="Checked vs. Runtime Exception" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><thr:total>1</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2010/04/checked-vs-runtime-exception.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEGQX08fCp7ImA9WxBVFUg.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-7659565587716389122</id><published>2010-01-20T16:11:00.001-08:00</published><updated>2010-02-18T20:43:40.374-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-18T20:43:40.374-08:00</app:edited><title>GWT + JEE Blueprint</title><content type="html">&lt;br&gt;&lt;div&gt;&lt;b&gt;&lt;font size="3"&gt;&lt;font color="#E06666"&gt;&lt;u&gt;Update&lt;/u&gt;&lt;/font&gt;&lt;/font&gt;&lt;/b&gt;: Java Source available at&amp;nbsp;&lt;a href="http://code.google.com/p/xsonymathew/"&gt;http://code.google.com/p/xsonymathew/&lt;/a&gt;&lt;/div&gt;&lt;br&gt; GWT is a true gem in the world of open-source slosh where most products are shiny gimmicks with little or no added value.&amp;nbsp; GWT accomplishes this mind-boggling feat of compiling Java source including much of Java&amp;#39;s core classes into JavaScript/HTML perfection.&amp;nbsp; JavaScript/HTML being this world of icky sludge that many (like me) would rather avoid stepping into with our tidy feet, maintaining our elitist staticky Object-Oriented (OO) attitude to everything while building great Rich Internet Applications (RIAs) that can &lt;u&gt;out-rich&lt;/u&gt; most other RIAs.&amp;nbsp; We can now use our IDEs to navigate and refactor across our entire tidy codebase and actually maintain our Apps for the long-term across a large team.&amp;nbsp; We can now apply a more uniform OO design across our entire application as sharing of Java source across tiers is now possible.&amp;nbsp; Componentization of UI into reusable widgets is now just a matter of OO design.&lt;br&gt;&lt;br&gt; Of course, Its not all peaches and cream with this hot and sexy GWT - waiting for GWT to finish can shrivel up most anybody&amp;#39;s confidence.&amp;nbsp; I outlined some of the issues with GWT in an earlier Article - the biggest being the relatively long compile waits - something you learn to compensate for in other ways.&amp;nbsp; Also to the contrary, you still need to understand HTML and CSS pretty well to use GWT effectively.&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt; Outlined are some of the key Concepts and Stereotypes we employ across our GWT and JEE Application.&amp;nbsp; Code samples and Diagrams are shown after the outline.&lt;/font&gt;&lt;br&gt;&lt;h3&gt;Inversion Of Control (IoC)&lt;/h3&gt; IoC is a concept we employ across our JEE Application including within our GWT tier for maximum separation of concerns.&amp;nbsp; There are many options for IoC available for Java in general but &lt;u&gt;hardly&lt;/u&gt; any for GWT where everything is statically analyzed upfront in compilation and Java Reflection cannot be used.&amp;nbsp; In fact, I would have said that none were available at the time of this writing, except I was corrected that Google GIN based on Google Guice was on its way to being released.&amp;nbsp; Luckily we rely on a design pattern for IoC which worked perfectly for our GWT application needs as well.&lt;br&gt;&lt;br&gt;&lt;ul&gt;&lt;li&gt;Use the Context IoC Design Pattern. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; See Article: &lt;a href="http://sonymathew.blogspot.com/2009/11/context-ioc-revisited-i-wrote-about.html" id="kqz2" title="Context IoC Revisited"&gt;Context IoC Revisited&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;u&gt;Important Constraints:&lt;/u&gt;&lt;br&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Browser-side bindings must be distinct from Server-side bindings.&lt;br&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;They may share common Java source e.g. DomainBeans/Models.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Browser-side bindings must be GWT compilable.&lt;/li&gt;&lt;li&gt;Browser-side bindings must be scoped to a GWT Module.&lt;/li&gt;&lt;li&gt;Server-side bindings must be scoped to a User&amp;#39;s Session.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;h3&gt;Event &amp;amp; EventManager&lt;/h3&gt;&lt;p&gt;We initially introduced an EventManager to &lt;u&gt;fire&lt;/u&gt; and &lt;u&gt;listen&lt;/u&gt; to Events and elegantly manage the &lt;u&gt;Asynchronous&lt;/u&gt; nature of Browser-side work.&amp;nbsp; Later We extended this to also &lt;u&gt;process&lt;/u&gt; Events &lt;u&gt;Synchronously&lt;/u&gt; as well which could then be leveraged Server-Side.&amp;nbsp; Finally, tired of the tediousness of GWT-RPC, We decided to just connect the two sides by introducing the &lt;u&gt;RemoteEvent Framework&lt;/u&gt; which transparently delivered RemoteRequestEvents sub-types fired locally Browser-side to the Server-Side and returned the response back to the Browser and fired for asynchronous listeners of the response.&amp;nbsp; This &lt;u&gt;greatly enhanced and simplified our RPC&lt;/u&gt; - Panels now merely fired and listened to Events for Server-side processing.&amp;nbsp; We also now had a &lt;u&gt;unified and universal Event Management approach&lt;/u&gt; across all tiers.&amp;nbsp; Finally, We also introduced a ViewEvent that could be sub-typed for easy tokenization and &lt;u&gt;browser history management&lt;/u&gt; when fired.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Events capture interesting Actions or Requests or Responses within your System.&lt;/li&gt;&lt;li&gt;Events can be &lt;u&gt;fired&lt;/u&gt; or &lt;u&gt;listened&lt;/u&gt; to for &lt;u&gt;Asynchronous&lt;/u&gt; processing using a local EventManager obtained via IoC. &lt;/li&gt;&lt;li&gt; Events of type RequestEvent can be &lt;u&gt;processed&lt;/u&gt; &lt;u&gt;Synchronously&lt;/u&gt; using a local EventManager obtained via IoC. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; Synchronous processing of an Event provides an immediate ResponseEvent sub-type returned to the caller. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt; Events fired of type RemoteRequestEvent will be &lt;u&gt;remotely processed Asynchronously&lt;/u&gt; via the &lt;u&gt;RemoteEvent Framework&lt;/u&gt;. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;The correct sub-type of RemoteResponseEvent is returned and fired locally upon completion of Server-side processing.&lt;br&gt;&lt;/li&gt;&lt;li&gt;See section: RemoteControl, RemoteEvent &amp;amp; RemoteEvent Framework.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Events can capture UI Actions (e.g. Resize, ViewCart), User Actions (e.g Submit) or Usecase Actions (e.g. PurchaseItems). &lt;/li&gt;&lt;ul&gt;&lt;li&gt;Can be triggered via a User&amp;#39;s action or internally fired as part of Application flow. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt; Events define their &lt;u&gt;Listener&lt;/u&gt; as an &lt;u&gt;inner-interface&lt;/u&gt; unique to it, to be implemented by interested listeners. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;The Listener&amp;#39;s onEvent() signature must accept the exact type of Event.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt; RequestEvent subtypes define their &lt;u&gt;Processor&lt;/u&gt; as an &lt;u&gt;inner-interface&lt;/u&gt; unique to it, to be implemented by interested Processors. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;The Processor&amp;#39;s process() signature must accept the exact type of RemoteResponseEvent.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Events should NOT access state static or otherwise external to themselves or their composition.&lt;br&gt;&lt;/li&gt;&lt;li&gt; Events should NOT use IoC or reference other Stereotypes and should be constructable. &lt;/li&gt;&lt;li&gt; Events should NOT fire, listen or process other Events or access the EventManager via IoC. &lt;/li&gt;&lt;/ul&gt;&lt;h3&gt; Panel &amp;amp; Widget &lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Panels and Widgets live solely on the Client-side (Browser-side). &lt;/li&gt;&lt;li&gt; All Panels concerned with Application flow should be CustomPanels (extends CustomPanel). &lt;/li&gt;&lt;li&gt; CustomPanels render rich visual user application flow - built using GWT&amp;#39;s Panels and Widgets.&lt;/li&gt;&lt;li&gt;CustomPanels can maintain presentation state on behalf of the user, but should refrain from holding domain state.&lt;br&gt;&lt;/li&gt;&lt;li&gt; CustomPanels access domain state via Models obtained via IoC. They may also update these Models. &lt;/li&gt;&lt;li&gt; CustomPanels may access various Formatters and similar types of utilities via IoC. &lt;/li&gt;&lt;li&gt; CustomPanels may access the EventManager via IoC and &lt;u&gt;fire&lt;/u&gt; | &lt;u&gt;listen&lt;/u&gt; Events. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;CustomPanel base class provides convenience methods to fire | listen Events. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt; CustomPanels should avoid accessing other Stereotypes via IoC that are not mentioned in this section. &lt;/li&gt;&lt;li&gt;CustomPanels should &lt;u&gt;explicitly destroy&lt;/u&gt; children that it no longer requires. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;u&gt;Rule of thumb&lt;/u&gt;: If re-assigning a member field then destroy() it. &lt;/li&gt;&lt;li&gt; CustomPanel base class provides convenience methods to destroy(Widget) including children. &lt;/li&gt;&lt;li&gt; Proper destruction ensures that all CustomPanels attached to the EventManager are de-registered. &lt;/li&gt;&lt;li&gt;A CustomPanel can optionally choose to destroy() itself and then re-initalize itself. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; Note: CustomPanel can re-register for Events it was listening to before its destruction. &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt; Utility components not concerned with Application specific flow may directly extend GWT&amp;#39;s Panel, Composite or Widget. &lt;/li&gt;&lt;ul&gt;&lt;li&gt;Utility components should NOT access the EventManager or other Stereotypes via IoC.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;CustomPanel designers should define appropriate ViewEvent subtypes to activate their Panels.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;To activate their Panel listen for their specific ViewEvents and fire an appropriately configured BorderUpdateEvent.&lt;/li&gt;&lt;li&gt;ViewEvent base class provides facilities to tokenize an event for &lt;u&gt;Browser History management&lt;/u&gt;.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;h3&gt; Model &lt;/h3&gt;&lt;ul&gt;&lt;li&gt; Models capture state as a &lt;u&gt;closed&lt;/u&gt; composition of DomainBeans, their associations, and operations that apply solely on itself and its children. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; Models may be composed of other Models and may operate on them as well. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Models should &lt;u&gt;NOT access state&lt;/u&gt; static or otherwise external to themselves or their composition.&lt;br&gt;&lt;/li&gt;&lt;li&gt; Models should NOT use IoC to reference other Stereotypes. &lt;/li&gt;&lt;li&gt; Models should NOT fire, listen or process Events nor access the EventManager via IoC. &lt;/li&gt;&lt;li&gt; Models should always be transportable and valid/equal on all tiers including Client-tier. &lt;/li&gt;&lt;li&gt; Models should be constructable on any tier including Client-side with a life-span determined by its scope. &lt;/li&gt;&lt;li&gt; Models may be referenced by other Stereotypes via IoC if it is a shared instance of user session scope. &lt;/li&gt;&lt;/ul&gt;&lt;h3&gt; RemoteControl, RemoteEvent &amp;amp; RemoteEvent Framework &lt;/h3&gt;&lt;ul&gt;&lt;li&gt; RemoteControls live solely on the Server-side and replaces the former stereotype Control. &lt;/li&gt;&lt;li&gt; RemoteControls (like the former Control) process domain actions and maintain domain state on behalf of the User.&lt;br&gt;&lt;/li&gt;&lt;li&gt;RemoteControls (like the former Control) are &lt;u&gt;Stateful&lt;/u&gt; and hold domain state on behalf of the User. &lt;br&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Either internally or via one or more shared Models.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt; RemoteControls can be accessed by other Server-Side Stereotypes via IoC. &lt;/li&gt;&lt;li&gt; RemoteControls can &lt;u&gt;process&lt;/u&gt; &lt;u&gt;RemoteRequestEvents&lt;/u&gt; fired Client-side and delivered Server-side via the &lt;u&gt;RemoteEvent Framework&lt;/u&gt;. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; They must register as a Processor for the exact sub-type of a RemoteRequestEvent with their local EventManager. &lt;/li&gt;&lt;li&gt; Events extending RemoteRequestEvent when fired Client-side will automatically be serialized and delivered to the registered Processor Server-side. &lt;/li&gt;&lt;/ul&gt;&lt;li&gt; RemoteControls produce &lt;u&gt;RemoteReponseEvents&lt;/u&gt; sub-types to be delivered via the RemoteEvent Framework back to Listeners Client-side. &lt;/li&gt;&lt;ul&gt;&lt;li&gt; Events extending RemoteReponseEvent will be automatically serialized and delivered to the registered Listeners Client-side. &lt;/li&gt;&lt;li&gt; CustomPanels interested in responses to fired events should register themselves as listeners with their local EventManager. &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;h3&gt; Service, Store, DomainBean&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Services and Stores live solely on the Server-side.&lt;br&gt;&lt;/li&gt;&lt;li&gt;Services are always &lt;u&gt;Stateless&lt;/u&gt; and implement transaction-level Usecases.&lt;/li&gt;&lt;li&gt;Stores are always &lt;u&gt;Stateless&lt;/u&gt; and implement CRUD operations for DomainBeans residing in a Repository.&lt;br&gt;&lt;/li&gt;&lt;li&gt;DomainBeans should always be transportable and valid/equal on all tiers including Client-side. &lt;/li&gt;&lt;li&gt; DomainBeans should be constructable on any tier including Client-side with a life-span determined by its scope. &lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;h3&gt;Diagrams &amp;amp; Code Samples&lt;/h3&gt;&lt;p&gt;&lt;u&gt;Disclaimer&lt;/u&gt;: Diagrams &amp;amp; Code Samples are a mashup of actual content slashed up and modified to use the mocked sample of Shopping. If it doesn&amp;#39;t all make sense, I apologize, the parts are there to convey the approach even if the sample as a whole doesn&amp;#39;t always come together.&lt;/p&gt;&lt;br&gt;&lt;b&gt;Local Events &amp;amp; Panels&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;div id="r38j" style="text-align:left"&gt;&lt;img src="http://docs.google.com/File?id=dcdgkqb9_137d5bjp2f3_b" style="height:927px;width:1225px"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Remote Events &amp;amp; RemoteControls&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;div id="h0c:" style="text-align:left"&gt;&lt;img src="http://docs.google.com/File?id=dcdgkqb9_139cbj2s739_b" style="height:1024px;width:1738px"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;font size="3"&gt;&lt;b&gt;Code Samples:&lt;/b&gt;&lt;/font&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&lt;u&gt;Disclaimer&lt;/u&gt;: Diagrams &amp;amp; Code Samples are a mashup of actual content slashed up and modified to use the mocked sample of Shopping. If it doesn&amp;#39;t all make sense, I apologize, the parts are there to convey the approach even if the sample as a whole doesn&amp;#39;t always come together.&lt;/p&gt;&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="ulc5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font color="#cc0000"&gt;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;b style="color:#cc0000"&gt;Sample ViewEvent&lt;/b&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;* Fired and used Browser-side only.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;u style="color:#cc0000"&gt;Note&lt;/u&gt;&lt;font color="#cc0000"&gt;: Extend Event.class directly for non-history managed events.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*/&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt;&amp;nbsp;ViewProductSearchEvent&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;ViewEvent {&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a Listener for your event.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Listener&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;Event.Listener {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(ViewProductSearchEvent e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a method to delegate to your Listener by exact type.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;fire(Event.Listener listener) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((ViewProductSearchEvent.Listener)listener).onEvent(this);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; //optionally override methods set/getTokenProps()&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; //for additional history token state. &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt; }&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="urfo"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font color="#cc0000"&gt;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;b style="color:#cc0000"&gt;Sample RemoteRequestEvent.&lt;/b&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;* Fired Browser-side and serialized to Server-side.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*/&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt;&amp;nbsp;FindProductsEvent&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;RemoteRequestEvent {&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a Listener for your event.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Listener&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;Event.Listener {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(FindProductsEvent e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a method to delegate to your Listener by exact type.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;fire(Event.Listener listener) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((FindProductsEvent.Listener)listener).onEvent(&lt;font color="#0000ff"&gt;this&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a Processor for your event (for synchronous processing).&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Specify exact type of your request and response events.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class names.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */ &amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Processor&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;RequestEvent.Processor {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent process(FindProductsEvent e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a method to delegate to your Processor by exact type&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and return the exact type of your response.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Note: Mediator is a simple interface to access the Processor of an Event type.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; *&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Your Local EventManager implements this Mediator interface.&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class names.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;@Override&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent process(RequestEvent.Mediator mediator) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&amp;nbsp;((FindProductsEvent.Processor)(mediator.getProcessor(this))).process(&lt;font color="#0000ff"&gt;this&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&amp;nbsp;String searchText =&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Not shown: GWT Serialization also requires a default constructor.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp; &amp;nbsp; */&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsEvent(String searchText) {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.searchText = searchText;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;String getSearchText() {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&amp;nbsp;searchText;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * RequestEvents must implement, used for cache-able responses.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;@Override&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;String getKey() {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ToStringBuilder(getClass())&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;.append(&amp;quot;searchText&amp;quot;, searchText)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;.toString();&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt; }&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="kmoz"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font color="#cc0000"&gt;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;b style="color:#cc0000"&gt;Sample RemoteResponseEvent.&lt;/b&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;* Serialized after Server-side processing back to Browser and fired.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*/&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;RemoteResponseEvent {&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a Listener for your event.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Listener&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;Event.Listener {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void onEvent(FindProductsDoneEvent e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define a method to delegate to your Listener by exact type.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Always cookie-cutter, just change event class name.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;fire(Event.Listener listener) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ((FindProductsDoneEvent.Listener)listener).onEvent(&lt;font color="#0000ff"&gt;this&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&amp;nbsp;List&amp;lt;Products&amp;gt; result =&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&amp;nbsp;ProductSearchException ex =&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Success with result.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Not shown: GWT Serialization also requires a default constructor.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent(String requestKey, List&amp;lt;Product&amp;gt; result) {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;super&lt;/font&gt;(requestKey, Status.Success);&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.results = results;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Failed with exception.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent(String requestKey, ProductSearchException x) {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;super&lt;/font&gt;(requestKey, Status.Fail);&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.ex = x;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;List&amp;lt;Product&amp;gt; getResult() {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&amp;nbsp;results;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;ProductSearchException getException() {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return ex;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt; }&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="xx34"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font color="#cc0000"&gt;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;b style="color:#cc0000"&gt;Sample Panel for shopping&lt;/b&gt;&lt;font color="#cc0000"&gt;.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;* Base CustomPanel class provides following shortcuts:&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp; listen(eventClass) =&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getEventManager().addListener(eventClass, this);&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp; fire(event) =&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getEventManager().fire(event);&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*/&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#0000ff"&gt;public class&lt;/font&gt;&amp;nbsp;ShoppingPanel&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;CustomPanel&amp;nbsp;&lt;font color="#0000ff"&gt;implements&lt;/font&gt;&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; ViewShoppingEvent.Listener, ViewProductSearchEvent.Listener&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoginDoneEvent.Listener, FindProductsDoneEvent.Listener,&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddToCartDoneEvent.Listener, PurchaseDoneEvent.Listener&lt;br&gt; {&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define my IoC dependencies.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Note CustomPanel.Context already specifies a dependency to EventManager.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Context&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;CustomPanel.Context {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ShoppingModel getShoppingModel();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private final&lt;/font&gt;&amp;nbsp;Context cxt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&amp;nbsp;Widgets widgets =&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Construct with my IoC Context defined above.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#38761d"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; public ShoppingPanel(Context cxt) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;super&lt;/font&gt;(cxt);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cxt = cxt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Build my panel.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;CustomPanel build() {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (isBuilt()) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#cc0000"&gt;//use base class shortcuts to register as listeners of events.&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(ViewShoppingEvent.class);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(ViewProductSearchEvent.class);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(LoginDoneEvent.class);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(FindProductsDoneEvent.class);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(AddToCartDoneEvent.class);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(PurchaseDoneEvent.class);&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;font color="#ff0000"&gt;//I&amp;#39;ve put my widgets into an inner class for easy manage.&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; widgets =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Widgets();&lt;br&gt;&lt;br&gt;&lt;font color="#ff0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;//Will be built later as product results are added&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; widgets.productResults.table.pad(5).space(0).width(&amp;quot;100%&amp;quot;).css(&amp;quot;shoppingTable&amp;quot;);&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#cc0000"&gt;//x(),y() are fluent api for Horizontal/Vertical layout (= x/y axis).&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; widgets.main.width(&amp;quot;100%&amp;quot;).css(&amp;quot;shoppingMain&amp;quot;)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x(widgets.breadcrumb).id(&amp;quot;breadCrumb&amp;quot;).width(&amp;quot;100%&amp;quot;).q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .y().width(&amp;quot;100%&amp;quot;).css(&amp;quot;shoppingSearch&amp;quot;)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x().stretch().align(-1,0).space(5)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .put(widgets.productSearch.searchText)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .put(widgets.productSearch.search)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x().stretch().align(1,0).space(5)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .put(widgets.newSearch)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .put(widgets.print)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x(horizontalLine()).width(&amp;quot;100%&amp;quot;).style(&amp;quot;margin&amp;quot;, &amp;quot;1em 0&amp;quot;).q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x(widgets.productResults.table).width(&amp;quot;100%&amp;quot;).q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .x(widgets.productResults.viewAlternatives).width(&amp;quot;100%&amp;quot;).align(1,0).space(6).q()&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ;&lt;font color="#cc0000"&gt;//end&lt;/font&gt;&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;CSSPanel().css(&amp;quot;shoppingDecor&amp;quot;).wrap(widgets.main));&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#cc0000"&gt;//Sample fire of RemoteRequestEvent for Server-side processing.&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; widgets.productSearch.search.addClickHandler(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ClickHandler() {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;public void onClick(ClickEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;FindProductsEvent(widgets.productSearch.searchText.getText());&lt;br&gt;&lt;font color="#0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ShowWorkingPopupEvent(&amp;quot;Searching Products&amp;quot;));&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;});&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle Event to display myself.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(ViewShoppingEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;BorderUpdateEvent(&lt;font color="#0000ff"&gt;this&lt;/font&gt;));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle Event to display self&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; *&amp;nbsp;&amp;nbsp; with product search.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(ViewProductSearchEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.getSearchText() !=&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;FindProductsEvent(e.getSearchText()));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ShowWorkingPopupEvent(&amp;quot;Searching Products&amp;quot;));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;BorderUpdateEvent(&lt;font color="#0000ff"&gt;this&lt;/font&gt;));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle server response to product search.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(FindProductsDoneEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;fire&lt;/font&gt;(&lt;font color="#0000ff"&gt;new &lt;/font&gt;HideWorkingPopupEvent());&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.isFail()) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errorAlert(e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getShoppingModel().addProductsSearched(e.getSearchText(), e.getResult());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updateProductResultsView();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle server response to cart add.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(AddToCartDoneEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.isFail()) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errorAlert(e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getShoppingModel().addToCart(e.getResult());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updateCartView();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle server response to purchasing.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(PurchaseDoneEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.isFail()) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errorAlert(e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getShoppingModel().setOrder(e.getOrder());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getShoppingModel().clearCart();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; updateOrderView();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; * Sample: handle server response to login.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;onEvent(LoginDoneEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e.isFail()) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; errorAlert(e);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getShoppingModel().resetCart();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //Collecting my widgets into inner classes for easy create/destroy/manage.&lt;/font&gt;&lt;br&gt;&lt;font color="#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; //These widgets are spread across a giant table due to biz requirements.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#cc0000"&gt;//Refactor into independent panels if can standalone.&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;br&gt;&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private class&lt;/font&gt;&amp;nbsp;Widgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BreadCrumbPanel breadcrumb =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;BreadCrumbPanel();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button newSearch =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Button(&amp;quot;NEW SEARCH&amp;quot;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button print =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Button(&amp;quot;PRINT&amp;quot;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductSearchWidgets productSearch =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductSearchWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;ProductResultWidgets&amp;gt; productResults =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductResultWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AxisPanel main =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;AxisPanel();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ProductSearchWidgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TextBox searchText =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;TextBox();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button search =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Button();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ProductResultWidgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductWidgets mainProduct =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductWidgets similarProduct =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Button viewAlternatives =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Button(&amp;quot;VIEW ALTERNATIVES&amp;quot;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AxisTable table =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;AxisTable();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ProductWidgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductDescWidgets desc =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductDescWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ProductCostsWidgets pricing =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;ProductPricingWidgets();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ProductDescWidgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Label name =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Label(&amp;quot;&amp;quot;, false);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Label brand =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Label(&amp;quot;&amp;quot;, false);&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&amp;nbsp;setDesc(Product product) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; name.setText(product.getName());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; brand.setText(product.getBrand());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&amp;nbsp;&lt;/font&gt;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ProductCostsWidgets {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CSSPanel productCost =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;CSSPanel();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CSSPanel shippingCost =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;CSSPanel();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CSSPanel savings =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;CSSPanel();&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&amp;nbsp;setCosts(Product product, Pricing pricing) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (pricing !=&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; productCost.put(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Label(&amp;quot;$&amp;quot; + pricing.getProductCost()));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; shippingCost.put(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Label(&amp;quot;$&amp;quot; + pricing.getShippingCost()));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; savings.put(&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Label(&amp;quot;$&amp;quot; + pricing.getSavings()));&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //More code..more widgets, updating widgets etc.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&lt;/font&gt;&lt;br style="color:#38761d"&gt; }&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;table border="1" bordercolor="#000000" cellpadding="3" cellspacing="0" id="fszm"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="100%"&gt;&lt;font color="#cc0000"&gt;/**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&lt;/font&gt;&lt;b style="color:#cc0000"&gt;A Sample RemoteControl.&lt;/b&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&lt;/font&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;* Base RemoteControl class provides the following shortcuts&lt;/font&gt;:&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp; process(eventClass) =&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getEventManager().addProcessor(eventClass, this);&lt;/font&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp; listen(eventClass) =&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getEventManager().addListener(eventClass, this);&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp; fire(event) =&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getEventManager().fire(event);&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;*/&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;class&lt;/font&gt;&amp;nbsp;ShoppingRemoteControlImpl&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;RemoteControl&amp;nbsp;&lt;font color="#0000ff"&gt;implements&lt;/font&gt;&amp;nbsp;ShoppingRemoteControl,&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp; &amp;nbsp;FindProductsEvent.Processor, AddToCartEvent.Processor, PurchaseEvent.Processor,&amp;nbsp;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LoginDoneEvent.Listener&lt;br&gt; {&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Define my IoC dependencies.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Note RemoteControl.Context already specifies a dependency to EventManager.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public interface&lt;/font&gt;&amp;nbsp;Context&amp;nbsp;&lt;font color="#0000ff"&gt;extends&lt;/font&gt;&amp;nbsp;RemoteControl.Context {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;UserRemoteControl getUserRemoteControl();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;ProductSearchService getProductSearchService();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;OrderService getOrderService();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;CartService getCartService();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private final&lt;/font&gt;&amp;nbsp;Context cxt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;private&lt;/font&gt;&amp;nbsp;Cart cart =&amp;nbsp;&lt;font color="#0000ff"&gt;null&lt;/font&gt;;&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * Construct with the IoC context defined above.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;ShoppingRemoteControlImpl(Context cxt) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;super&lt;/font&gt;(ctx);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cxt = cxt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cart =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Cart();&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //register as processor of events&amp;nbsp;&lt;/font&gt;&lt;font color="#cc0000"&gt;using base class shortcuts.&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;process&lt;/font&gt;(FindProductsEvent&lt;font color="#0000ff"&gt;.class&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;process&lt;/font&gt;(AddToCartEvent&lt;font color="#0000ff"&gt;.class&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;process&lt;/font&gt;(PurchaseEvent&lt;font color="#0000ff"&gt;.class&lt;/font&gt;);&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //register as listener of events&amp;nbsp;&lt;/font&gt;&lt;font color="#cc0000"&gt;using base class shortcuts.&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;listen&lt;/font&gt;(LoginDoneEvent&lt;font color="#0000ff"&gt;.class&lt;/font&gt;);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * process request arriving remotely.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;AddToCartDoneEvent process(AddToCartEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;this.&lt;/font&gt;addToCart(e.getProduct(), e.getQuantity());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return new&amp;nbsp;&lt;/font&gt;AddToCartDoneEvent(e.getKey());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * process request arriving remotely.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;FindProductsDoneEvent process(FindProductsEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;Products&amp;gt; products = &lt;font color="#0000ff"&gt;this.&lt;/font&gt;findProducts(e.getSearchText());&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return new&amp;nbsp;&lt;/font&gt;FindProductsDoneEvent(e.getKey(), products);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * process request arriving remotely.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;PurchaseDoneEvent process(PurchaseEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Order order = &lt;font color="#0000ff"&gt;this.&lt;/font&gt;purchaseCart();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return new&amp;nbsp;&lt;/font&gt;PurchaseDoneEvent(e.getKey(), order);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * listen (not process) a request arriving remotely.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;&lt;font color="#0000ff"&gt;void&lt;/font&gt;&amp;nbsp;onEvent(LoginDoneEvent e) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UserKey userKey = cxt.getUserRemoteControl().getUser().getKey();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cart = cxt.getCartService().getLastSavedCart(userKey);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * impl of biz interface.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br style="color:#cc0000"&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;List&amp;lt;Products&amp;gt; findProducts(String text) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UserKey userKey = cxt.getUserRemoteControl().getUser().getKey();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; List&amp;lt;Products&amp;gt; results = cxt.getProductSearchService().findProducts(userKey, text);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;return&lt;/font&gt;&amp;nbsp;results;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * impl of biz interface.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public&lt;/font&gt;&amp;nbsp;Order purchaseCart() {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UserKey userKey = cxt.getUserRemoteControl().getUser().getKey();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Order order = cxt.getOrderService().purchase(userKey, &lt;font color="#0000ff"&gt;this.&lt;/font&gt;cart);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getCartService().clearSavedCart(userKey);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cart =&amp;nbsp;&lt;font color="#0000ff"&gt;new&amp;nbsp;&lt;/font&gt;Cart();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color="#0000ff"&gt;return&lt;/font&gt; order;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * impl of biz interface.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;addToCart(Product product, BigDecimal quantity) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UserKey userKey = cxt.getUserRemoteControl().getUser().getKey();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getCartService().addToSavedCart(userKey, product, quantity);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this.&lt;/font&gt;cart.add(product,quantity);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp; /**&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; * impl of biz interface.&lt;/font&gt;&lt;br style="color:#cc0000"&gt;&lt;font color="#cc0000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; */&lt;/font&gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;public void&lt;/font&gt;&amp;nbsp;removeFromCart(Product p) {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; UserKey userKey = cxt.getUserRemoteControl().getUser().getKey();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cxt.getCartService().removeFromSavedCart(userKey, product);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.cart.remove(product);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; }&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&lt;br&gt;&lt;font size="4"&gt;&lt;b&gt;Conclusion:&lt;/b&gt;&lt;/font&gt;&lt;br&gt; Draw your own conclusions!!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-7659565587716389122?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vVv3k6V1KTyXF2pYa_ILnlOj0J8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vVv3k6V1KTyXF2pYa_ILnlOj0J8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vVv3k6V1KTyXF2pYa_ILnlOj0J8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vVv3k6V1KTyXF2pYa_ILnlOj0J8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/NI1Bvcn7NqI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/7659565587716389122/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=7659565587716389122" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/7659565587716389122?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/7659565587716389122?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/NI1Bvcn7NqI/gwt-jee-blueprint.html" title="GWT + JEE Blueprint" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><thr:total>5</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2010/01/gwt-jee-blueprint.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YGRHw9eyp7ImA9WxNaFUQ.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-661066751409621636</id><published>2009-11-27T13:35:00.001-08:00</published><updated>2009-11-30T08:38:45.263-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-30T08:38:45.263-08:00</app:edited><title>Context IoC Revisted</title><content type="html">&lt;span style="font-family: 'Times New Roman';"&gt;
&lt;div style="margin: 6px; font-family: Verdana; background-color: rgb(255, 255, 255); direction: ltr;"&gt;
&lt;div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;I wrote about the&amp;nbsp;&lt;a id="pjz3" href="http://www.theserverside.com/tt/articles/content/IOCandEJB/article.html" title="Context IoC" style="color: rgb(85, 26, 139);"&gt;Context IoC&lt;/a&gt;&amp;nbsp;Design Pattern a while back now (Feb-2005) and &lt;a id="w45:" href="http://hinchcliffe.org/archive/2005/02/24/183.aspx" title="few people" style="color: rgb(85, 26, 139);"&gt;some people&lt;/a&gt;&amp;nbsp;picked up on it right away.&amp;nbsp; I even caught a C++ equivalent of Context IoC on the &lt;a title="google testing blog site" href="http://googletesting.blogspot.com/2008/10/tott-contain-your-environment.html" id="egfy"&gt;google testing blog site&lt;/a&gt;. I have also seen similar patterns used in Scala and other languages. &amp;nbsp;IoC containers are still popular (mostly for Java) and new ones have come on the scene like&amp;nbsp;&lt;a id="bfuo" href="http://code.google.com/p/google-guice/" title="Guice" style="color: rgb(85, 26, 139);"&gt;Guice&lt;/a&gt;&amp;nbsp;which use Annotations to address many of the concerns I had initially outlined.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;Here are some of the arguments for Context IoC I've made in the past:&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;1) There simply isn't a better language for describing and instantiating Java objects and invoking Java methods than Java itself !!! &amp;nbsp;Use of a container for IoC means all construction and dependency semantics have to be described using secondary configurations (XML or Annotations) which are then interpreted and implemented at runtime. &amp;nbsp;They are inherently going to be slower and more complex than direct Java construction and wiring.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
2) The big advantage of Context IoC is type safety. &amp;nbsp;Context IoC Design Pattern does NOT use string identifiers to wire dependencies together. &amp;nbsp;Annotations can eliminate this problem as well if done right by an IoC Container Framework.&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;&lt;h2&gt;Comparing against Annotation based Dependency Injection&lt;br&gt;&lt;/h2&gt;
&lt;p&gt;I'm still mixed about Annotation based Dependency wiring. &amp;nbsp;Annotations are a fabulous feature and I had fully expected them to change the landscape of containers - but its intent was for containers to post-process code as an after-thought to provide deployment level mappings rather than be used as the central engine for wiring our code. &amp;nbsp;&lt;u&gt;Annotations can be processed differently environment to environment and left to container interpretations&lt;/u&gt; which is not appropriate for application flow in my opinion (unless of course you sell your soul to a single container maker).&lt;/p&gt;&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;In any case Annotations do address some of the issues I outlined against XML|String wired IoC containers - so Let us compare Context IoC and Annotation based Dependency Injections (DI).&lt;/div&gt;&lt;div style="text-align: left;"&gt;
&lt;div&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div&gt;&lt;b&gt;Annotation based Dependency Injection:&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp;&amp;nbsp;public class MyService implements SomeService {&amp;nbsp;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private CommonService blue = null;
&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private CommonService red = null;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Inject //&lt;span style="color: rgb(255, 0, 0);"&gt;imported from com.third.party.ioc.container&lt;/span&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setBlue(@Blue CommonService blue) {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; this.blue = blue;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Inject //&lt;span style="color: rgb(255, 0, 0);"&gt;imported from com.third.party.ioc.container&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setRed(@Red CommonService red) {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; this.red = red;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br&gt;
&lt;/div&gt;
&lt;b&gt;Context IoC based&amp;nbsp;&lt;b&gt;Dependency Injection&lt;/b&gt;:&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp; public class MyService implements SomeService {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public interface Context {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CommonService getBlue();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CommonService getRed();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private final Context cxt;&lt;/font&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public MyService(Context cxt) {&lt;/font&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;this.cxt = cxt;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp; }&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
Not much different in expressiveness. &amp;nbsp;With the Annotation based framework however you create a binding using the framework's proprietary classes that read the annotations at runtime and interpret your intentions to create the appropriate wirings. &amp;nbsp;With Context IoC you own your bindings - just implement your Contexts. You can create your bindings per package or per module or per application. &amp;nbsp;Your bindings merely implement &lt;u&gt;all&lt;/u&gt; the Contexts you choose to assemble as a module or application. &amp;nbsp;With this approach you can refactor your Contexts and Bindings, &amp;nbsp;generalize them or decompose them - it is just Java, it is just OO and best of all it is your code, not extending some proprietary framework sprinkled with proprietary annotations. &amp;nbsp;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;b&gt;Annotation based Binding:&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;b&gt;com.third.party.ioc.container.ProprietaryBinding&lt;/b&gt; binding = new &lt;b&gt;com.third.party.ioc.container.ProprietaryBinding&lt;/b&gt;();&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;br&gt;binding.bind(SomeService.class)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; .to(MyService.class);&lt;br&gt;&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;binding.bind(CommonService.class)&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;.annotatedWith(Blue.class)&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;.to(BlueService.class);&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;binding.bind(CommonService.class)&lt;br&gt;&amp;nbsp;&amp;nbsp;.annotatedWith(Red.class)&lt;br&gt;&amp;nbsp;&amp;nbsp;.to(RedService.class);&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;b&gt;Context IoC Binding:&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;public class MyBinding implements &lt;/font&gt;&lt;font style="color: rgb(255, 0, 0);" class="Apple-style-span" face="'Courier New'"&gt;MyService.Context&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt; {&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp; private final SomeService main;&lt;br&gt;&amp;nbsp; private final CommonService blue;&lt;br&gt;
&amp;nbsp; private final CommonService red;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp; public MyBinding() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main = new MyService(&lt;/font&gt;&lt;font style="color: rgb(255, 0, 0);" class="Apple-style-span" face="'Courier New'"&gt;this&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;);&lt;/font&gt; &lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;//pass 'this' as context.&lt;/font&gt;&lt;/font&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; blue = new BlueService();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; red = new RedService();&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&amp;nbsp; &lt;br&gt;&amp;nbsp; public SomeService getMain() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return main;&lt;br&gt;&amp;nbsp; }&lt;br&gt;&lt;br&gt;
&amp;nbsp; public CommonService getBlue() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return blue;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp; public CommonService getRed() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return red;&lt;br&gt;
&amp;nbsp; }&amp;nbsp;&amp;nbsp;&lt;br&gt;
}&lt;/font&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/span&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;Both bindings can be compile safe in Java, however, compile safety in the Annotation based binding is provided via the 3rd-party container's &lt;font class="Apple-style-span" face="'Courier New'"&gt;ProprietaryBinding&lt;/font&gt; whose method signatures enforce compile safety via generics, while the Context IoC binding is pure and simple Java and reliant only on your IDE or Java compiler for safety and not on an API to enforce compile safety (or for that matter bind your objects).&lt;br&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;How about if additional dependencies were needed - say BlueService needs yet another CommonService?&lt;/div&gt;
&lt;br&gt;
&lt;div style="text-align: left;"&gt;
&lt;div&gt;&lt;b&gt;Add a dependency via Annotation:&lt;/b&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp;&amp;nbsp;public class BlueService implements CommonService {&amp;nbsp;&amp;nbsp;&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;private CommonService green = null;
&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;@Inject &lt;/font&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;//&lt;span style="color: rgb(255, 0, 0);"&gt;imported from com.third.party.ioc.container&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void setGreen(@Green CommonService green) {&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.green = green;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;
&amp;nbsp; }&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div&gt;&lt;br&gt;
&lt;/div&gt;
&lt;b&gt;Add a dependency via Context IoC:&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;
&amp;nbsp; public class BlueService implements CommonService {&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public interface Context {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CommonService getGreen();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;private final Context cxt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public BlueService(Context cxt) {&lt;/font&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;this.cxt = cxt;&lt;br&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp; }&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;br&gt;
And the bindings would be updated to the following:&lt;br&gt;
&lt;br&gt;
&lt;div&gt;
&lt;div style="text-align: left;"&gt;&lt;b&gt;Annotation based Binding:&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;ProprietaryBinding binding = new ProprietaryBinding();&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;br&gt;&amp;nbsp; binding.bind(SomeService.class)&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; .to(MyService.class);&lt;br&gt;&lt;br&gt;&lt;/font&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;binding.bind(CommonService.class)&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;.annotatedWith(Blue.class)&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; .to(BlueService.class);&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;binding.bind(CommonService.class)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .annotatedWith(Red.class)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .to(RedService.class);&lt;/font&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp;&amp;nbsp;binding.bind(CommonService.class)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .annotatedWith(Green.class)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; .to(GreenService.class);&lt;/font&gt;&lt;/font&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;b&gt;Context IoC based Binding:&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;br&gt;
&lt;/div&gt;
&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;public class MyBinding implements MyService.Context, &lt;/font&gt;&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;BlueService.Context&lt;/font&gt;&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt; {&amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp; private final SomeService main;&lt;br&gt;&amp;nbsp; private final CommonService blue;&lt;br&gt;
&amp;nbsp; private final CommonService red;&lt;br&gt;&amp;nbsp; private final CommonService green;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp; public MyModule() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main = new MyService(this);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; blue = new BlueService(&lt;/font&gt;&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;this&lt;/font&gt;&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;); &lt;/font&gt;&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;//pass 'this' as context.&lt;/font&gt;&lt;/font&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; red = new RedService();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; green = new GreenService();&lt;br&gt;
&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp; public SomeService getMain() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return main;&lt;br&gt;&amp;nbsp; }&lt;br&gt;&amp;nbsp; &lt;br&gt;
&amp;nbsp; public CommonService getBlue() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return blue;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;br&gt;
&amp;nbsp; public CommonService getRed() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return red;&lt;br&gt;
&amp;nbsp; }&lt;br&gt;&lt;br&gt;&lt;/font&gt;
&lt;font class="Apple-style-span" color="#ff0000"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;&amp;nbsp; public CommonService getGreen() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return green;&lt;br&gt;&amp;nbsp; }&amp;nbsp; &lt;br&gt;&lt;/font&gt;&lt;/font&gt;&lt;br&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;font class="Apple-style-span" face="'Courier New'"&gt;}&lt;/font&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;br&gt;&lt;b&gt;Your friendly neighborhood &lt;font size="4"&gt;IDE&lt;/font&gt;&lt;/b&gt; &lt;b&gt;makes Context IoC clearly better&lt;/b&gt;!&lt;br&gt;Your IDE is your friend, and with Context IoC, as soon as you add a dependency to any Object's Context - your IDE lets you know all the bindings that need to be updated and fixed.&amp;nbsp; You may have one or more bindings in your application depending on how you modularize and of course one or more Unit-Test bindings as well that may need to be updated and fixed.&amp;nbsp; &lt;b&gt;&lt;u&gt;Here Context IoC is clearly better&lt;/u&gt;&lt;/b&gt; since an Annotation or XML based binding will not help identify these mistakes until you execute your App.&amp;nbsp; Annotation based bindings cannot provide compile safety if you never made a binding entry in the first place!&amp;nbsp; But your good old Java compiler and IDE will come to your rescue with Context IoC and tell you where all you have forgotten to provide a binding entry.&lt;br&gt;&lt;br&gt;&lt;h2&gt;Wrappers|Decorators|Interceptors&lt;/h2&gt;&lt;div&gt;Annotations should be used for what they are designed - provide external environmental binding points. &amp;nbsp;Annotations can now be post-processed by Wrappers|Decorators|Interceptors of your choosing based on how an application should be configured and deployed to an environment.&amp;nbsp; All forms of IoC Bindings (be it Context IoC or Annotation based or XML based) can easily allow for Wrappers or Decorators or Interceptors since any of these Bindings manage &lt;u&gt;Object construction&lt;/u&gt;.&amp;nbsp; Here again, If you are using a 3rd party IoC Container to manage your IoC Bindings - you will need to use their proprietary API or proprietary declaration to hook in your Decorator or Interceptor. (Note: Standardization can help alleviate some of this).&lt;/div&gt;&lt;br&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-661066751409621636?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T_c2WVNtS3kSShXeFYJTkPl8NSw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T_c2WVNtS3kSShXeFYJTkPl8NSw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T_c2WVNtS3kSShXeFYJTkPl8NSw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T_c2WVNtS3kSShXeFYJTkPl8NSw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/Ts1ItCxKwJg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/661066751409621636/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=661066751409621636" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/661066751409621636?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/661066751409621636?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/Ts1ItCxKwJg/context-ioc-revisited-i-wrote-about.html" title="Context IoC Revisted" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><thr:total>2</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2009/11/context-ioc-revisited-i-wrote-about.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ICQX89cSp7ImA9WxVXGU0.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-5599119693083425260</id><published>2009-02-17T10:55:00.002-08:00</published><updated>2009-02-17T14:26:00.169-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-17T14:26:00.169-08:00</app:edited><title>Comparing RIA Frameworks</title><content type="html">&lt;p&gt;
Giving a Rich face-lift to an organization's websites can deliver such a superior user experience that quite possibly it can give the organization a clear edge over its competitors, but choosing the right RIA framework for your team is never an easy task.  The frameworks, categories, and details presented in this article are not exhaustive by any means. 
&lt;/p&gt;

&lt;p&gt;
Reviewer: Sony Mathew: GWT 1.5, Laszlo 4.2, JavaScript Raw&lt;br&gt;
Reviewer: Mark Ulmer: Flex 3.2
&lt;/p&gt;

&lt;table border="1" cellpadding="2" width="1453" height="902"
 cellspacing="0"&gt;
 &lt;tbody align="center" valign="middle" style="font-family:Arial; font-size:11px"&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="blue"&gt;&lt;/td&gt;
   &lt;td bgcolor="#FFCC00" width="269"&gt;GWT 1.5 | AJAX&lt;/td&gt;
   &lt;td bgcolor="#FFCC00" width="272"&gt;Flex 3.2 | FLASH&lt;/td&gt;
   &lt;td bgcolor="#FFCC00" width="266"&gt;Laszlo 4.2 | AJAX&lt;/td&gt;
   &lt;td bgcolor="#FFCC00" width="270"&gt;Laszlo 4.2 | FLASH&lt;/td&gt;
   &lt;td bgcolor="#FFCC00" width="268"&gt;JavaScript Raw | AJAX&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00"&gt;Platform/Technology&lt;/td&gt;
   &lt;td width="269"&gt;Standard Browser &lt;br&gt;
   (HTML, JavaScript, AJAX).&lt;/td&gt;
   &lt;td width="272"&gt;FLASH &lt;br&gt;
   (Browser plug-in by Adobe)&lt;/td&gt;
   &lt;td width="266"&gt;Standard Browser &lt;br&gt;
   (HTML, JavaScript, AJAX).&lt;/td&gt;
   &lt;td width="270"&gt;FLASH &lt;br&gt;
   (Browser plug-in by Adobe)&lt;/td&gt;
   &lt;td width="268"&gt;Standard Browser &lt;br&gt;
   (HTML, JavaScript, AJAX).&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00"&gt;User Experience&lt;/td&gt;
   &lt;td width="269"&gt;Modest Rich&lt;br&gt;
   Approaching Desktop App feel&lt;br&gt;
   No Page refreshes, all data-access &amp;amp; rendering in the background.&lt;/td&gt;
   &lt;td width="272"&gt;Very Rich&lt;br&gt;
   Is exactly like a Desktop App&lt;br&gt;
   No Page refreshes, all data-access &amp;amp; rendering in the background.&lt;/td&gt;
   &lt;td width="266"&gt;Modest Rich&lt;br&gt;
   Approaching Desktop App feel&lt;br&gt;
   No Page refreshes, all data-access &amp;amp; rendering in the background.&lt;/td&gt;
   &lt;td width="270"&gt;Very Rich&lt;br&gt;
   Is exactly like a Desktop App&lt;br&gt;
   No Page refreshes, all data-access &amp;amp; rendering in the background.&lt;/td&gt;
   &lt;td width="268"&gt;Modest Rich&lt;br&gt;
   Approaching Desktop App feel&lt;br&gt;
   No Page refreshes, all data-access &amp;amp; rendering in the background.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="68"&gt;Browser Support&lt;/td&gt;
   &lt;td height="68" width="269"&gt;Relies on WWW standards. Supports
   all relevant browsers including IPhone &amp;amp; Android browsers.
   Incompatibility issues are minimized but still present e.g. with CSS
   or custom components.&lt;/td&gt;
   &lt;td height="68" width="272"&gt;Supports all relevant browsers
   including future Android browsers but not the IPhone. Zero
   incompatibility issues, but unlike standards plug-ins compete for
   user base.&lt;/td&gt;
   &lt;td height="68" width="266"&gt;Relies on WWW standards. Supports
   all relevant browsers including IPhone &amp;amp; Android browsers.
   Incompatibility issues are minimized but still present.&lt;/td&gt;
   &lt;td height="68" width="270"&gt;Supports all relevant browsers
   including future Android browsers but not the IPhone. Zero
   incompatibility issues, but unlike standards plug-ins compete for
   user base.&lt;/td&gt;
   &lt;td height="68" width="268"&gt;Relies on WWW standards. Can support
   all relevant browsers including IPhone &amp;amp; Android browsers.
   Incompatibility issues can be major unless using a 3rd party library.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="67"&gt;UI Code&lt;/td&gt;
   &lt;td height="67" width="269"&gt;Java, Compiled to JavaScript, Styled
   by standard CSS, Code HTML for Custom components. Some JRE not
   simulated e.g. BigDecimal, Calendar, DateFormat, NumberFormat but can
   fix.&lt;/td&gt;
   &lt;td height="67" width="272"&gt;XML markup &amp;amp; ActionScript
   (Javascript with OO &amp;amp; static typing). Compiled to Flash SWF.
   Styled by custom CSS.&lt;/td&gt;
   &lt;td height="67" width="266"&gt;XML markup &amp;amp; JavaScript,
   Compiled to JavaScript. Styled by custom CSS.&lt;/td&gt;
   &lt;td height="67" width="270"&gt;XML markup &amp;amp; JavaScript,
   Compiled to Flash SWF. Styled by custom CSS.&lt;/td&gt;
   &lt;td height="67" width="268"&gt;JavaScript &amp;amp; HTML DOM
   Manipulation. Styled by standard CSS.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="92"&gt;Access Remote
   Services &amp;amp; Data.&lt;/td&gt;
   &lt;td height="92" width="269"&gt;Invoke remote Java services and
   transport Java beans like RMI (Declare remote Java interfaces + Mark
   transported beans as Serializable + Java Servlet to process RPC
   requests). Can also do direct HTTP, transport XML or JSON to/from
   Servlet &amp;amp; use via their API for XPATH or JSON.&lt;/td&gt;
   &lt;td height="92" width="272"&gt;Configure access to any Java bean
   &amp;amp; transport beans as ActionScript objects. Can also do HTTP or
   SOAP, transport XML to/from Servlet &amp;amp; &amp;amp; use via easy XPATH
   bindings to views.&lt;/td&gt;
   &lt;td height="92" width="266"&gt;Can do HTTP or SOAP, transport XML
   to/from Servlet &amp;amp; use via easy XPATH bindings to views. Can also
   configure RPC directly to a Java bean &amp;amp; access transported beans
   as JavaScript objects.&lt;/td&gt;
   &lt;td height="92" width="270"&gt;Can do HTTP or SOAP, transport XML
   to/from Servlet &amp;amp; use via easy XPATH bindings to views. Can also
   configure RPC directly to a Java bean &amp;amp; access transported beans
   as JavaScript objects.&lt;/td&gt;
   &lt;td height="92" width="268"&gt;Can do HTTP, transport XML or JSON
   to/from Servlet &amp;amp; use via XPATH or JavaScript objects.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="56"&gt;Code Complexity
   Management&lt;/td&gt;
   &lt;td height="56" width="269"&gt;Java files, Compile-time type
   safety, Organize into Class/Object hierarchies, Packages, Modules.&lt;/td&gt;
   &lt;td height="56" width="272"&gt;XML Files &amp;amp; ActionScript files,
   Compile-time type safety, Organize into Class/Object hierarchies,
   Packages, Modules &amp;amp; Libraries.&lt;/td&gt;
   &lt;td height="56" width="266"&gt;XML Files, Organize into
   Object/Prototype hierarchies &amp;amp; Libraries.&lt;/td&gt;
   &lt;td height="56" width="270"&gt;XML Files, Organize into
   Object/Prototype hierarchies &amp;amp; Libraries.&lt;/td&gt;
   &lt;td height="56" width="268"&gt;JavaScript Files, Organize into
   Object/Prototype hierarchies.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="96"&gt;Tool Support /
   Eclipse Integration&lt;/td&gt;
   &lt;td height="96" width="269"&gt;Use all Java Tools, Free
   command-line Compile/Build or custom Eclipse plugin for
   Compile/Build. Run/Debug from Eclipse like regular Java. Navigate to
   API docs from Java Editor.&lt;/td&gt;
   &lt;td height="96" width="272"&gt;Use all XML Tools, Free command-line
   Compile/Build or Adobe Eclipse plugin ($250) for Compile/Build &amp;amp;
   Run/Debug &amp;amp; good graphical WYSIWYG editor. Navigate to API docs
   from XML or ActionScript Editor via Eclipse plugin.&lt;/td&gt;
   &lt;td height="96" width="266"&gt;Use all XML Tools, DTD/Schema not
   kept current &amp;amp; not usable if creating new object tags. Run from
   Browser and use interactive Debug console in Browser (console had
   some issues with IE). Switch between DHTML &amp;amp; FLASH 8 &amp;amp; 9.
   View separate online docs in browser - no navigation shortcut.&lt;/td&gt;
   &lt;td height="96" width="270"&gt;Use all XML Tools, DTD/Schema not
   kept current &amp;amp; not usable if creating new object tags. Run from
   Browser and use interactive Debug console in Browser. Switch between
   DHTML &amp;amp; FLASH 8 &amp;amp; 9. View separate online docs in browser -
   no navigation shortcut.&lt;/td&gt;
   &lt;td height="96" width="268"&gt;Edit with a Text or JavaScript
   Editor. Run from Browser - use FireBug and similar tools to debug.
   View separate online docs in browser - no navigation shortcut.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="51"&gt;Refactoring &amp;amp;
   Code-Completion Support&lt;/td&gt;
   &lt;td height="51" width="269"&gt;All Java Refactoring &amp;amp; Code
   Completion.&lt;/td&gt;
   &lt;td height="51" width="272"&gt;Eclipse plugin provides standard
   refactoring operations (rename, move, etc.) &amp;amp; Code-Completion.&lt;/td&gt;
   &lt;td height="51" width="266"&gt;Some XML
   Element/Attribute Completion but DTD/Schema not kept current &amp;amp;
   not usable if creating new object tags&lt;/td&gt;
   &lt;td height="51" width="270"&gt;Some XML
   Element/Attribute Completion but DTD/Schema not kept current &amp;amp;
   not usable if creating new object tags&lt;/td&gt;
   &lt;td height="51" width="268"&gt;None.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="45"&gt;JEE Integration&lt;/td&gt;
   &lt;td height="45" width="269"&gt;Lives in any WAR project. Generates
   JS files for inclusion in WAR.&lt;/td&gt;
   &lt;td height="45" width="272"&gt;Lives in any WAR project. Generates
   SWF files for inclusion in WAR or compile just-in-time at runtime.&lt;/td&gt;
   &lt;td height="45" width="266"&gt;Lives in any WAR project. Generates
   JS files for inclusion in WAR or compile just-in-time at runtime.
   Many jars (some unnecessary).&lt;/td&gt;
   &lt;td height="45" width="270"&gt;Lives in any WAR project. Generates
   SWF files for inclusion in WAR or compile just-in-time at runtime.
   Many jars (some unnecessary).&lt;/td&gt;
   &lt;td height="45" width="268"&gt;Lives in any WAR project. Include
   &amp;amp; Edit JS files in your WAR.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00"&gt;Migration&lt;/td&gt;
   &lt;td width="269"&gt;Can integrate with existing Web-Apps as new
   pages or part of a page, Allows deep links into workflows. Can reuse
   existing beans &amp;amp; can remote access to existing Controls &amp;amp;
   Services including sharing of session data.&lt;/td&gt;
   &lt;td width="272"&gt;Can integrate with existing Web-Apps as new
   pages only, Allows deep links into workflows. Can reuse existing
   beans &amp;amp; can remote access to existing Controls &amp;amp; Services
   including sharing of session data.&lt;/td&gt;
   &lt;td width="266"&gt;Can integrate with existing Web-Apps as new
   pages only, Allows deep links into workflows. Can reuse existing
   beans &amp;amp; can remote access to existing Controls &amp;amp; Services
   including sharing of session data.&lt;/td&gt;
   &lt;td width="270"&gt;Can integrate with existing Web-Apps as new
   pages only, Allows deep links into workflows. Can reuse existing
   beans &amp;amp; can remote access to existing Controls &amp;amp; Services
   including sharing of session data.&lt;/td&gt;
   &lt;td width="268"&gt;Can integrate with existing Web-Apps as new
   pages or part of a page, Allows deep links into workflows. Can reuse
   existing beans (with explicit JSON conversion) &amp;amp; can remote
   access to existing Controls &amp;amp; Services including sharing of
   session data.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="101"&gt;Performance&lt;/td&gt;
   &lt;td height="101" width="269"&gt;Fast download time to Browser, Fast
   startup time, Modest Browser Responsiveness (All relative to size of
   App). Can modularize to decrease download/startup times. Low
   bandwidth usage compared to traditional web apps.&lt;/td&gt;
   &lt;td height="101" width="272"&gt;Modest download time to Browser,
   Modest startup time, Fast Browser Responsiveness (All relative to
   size of App). Can modularize to decrease download/startup times. Low
   bandwidth usage compared to traditional web apps.&lt;/td&gt;
   &lt;td height="101" width="266"&gt;Modest download time to Browser,
   Modest startup time, Modest Browser Responsiveness (All relative to
   size of App). Can modularize to decrease download/startup times. Low
   bandwidth usage compared to traditional web apps.&lt;/td&gt;
   &lt;td height="101" width="270"&gt;Modest download time to Browser,
   Modest startup time, Fast Browser Responsiveness (All relative to
   size of App). Can modularize to decrease download/startup times. Low
   bandwidth usage compared to traditional web apps.&lt;/td&gt;
   &lt;td height="101" width="268"&gt;Modest download time to Browser,
   Modest startup time, Modest Browser Responsiveness (All relative to
   size of App). Can modularize to decrease download/startup times. Low
   bandwidth usage compared to traditional web apps.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="49"&gt;Static-Content
   (Externally Managed)&lt;/td&gt;
   &lt;td height="49" width="269"&gt;Can mixin HTML &amp;amp; CSS as-is or
   modified. Can parse XML content or plain-text.&lt;/td&gt;
   &lt;td height="49" width="272"&gt;Can parse XML content or plain-text.
   Can mixin basic HTML text (Not CSS) as-is.&lt;/td&gt;
   &lt;td height="49" width="266"&gt;Can parse XML content or plain-text.
   Can mixin basic HTML text (Not CSS) as-is.&lt;/td&gt;
   &lt;td height="49" width="270"&gt;Can parse XML content or plain-text.
   Can mixin basic HTML text (Not CSS) as-is.&lt;/td&gt;
   &lt;td height="49" width="268"&gt;Can mixin HTML &amp;amp; CSS as-is or
   modified. Can parse XML content or plain-text.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="52"&gt;Testing&lt;/td&gt;
   &lt;td height="52" width="269"&gt;Supports Unit Tests. There are
   various Record/Playback/Scripted tools e.g. Selenium. Load Testing ??
   (Script with HtmlUnit?)&lt;/td&gt;
   &lt;td height="52" width="272"&gt;Adobe provides FlexUnit for unit
   testing. There are various Record/Playback/Scripted tools:
   FlexMonkey, FlashSelenium, Mercury QuickTest. Load Testing ??&lt;/td&gt;
   &lt;td height="52" width="266"&gt;There are various
   Record/Playback/Scripted tools e.g. Selenium. Load Testing ?? (Script
   with HtmlUnit?)&lt;/td&gt;
   &lt;td height="52" width="270"&gt;There are various
   Record/Playback/Scripted tools: FlexMonkey, FlashSelenium, Mercury
   QuickTest. Load Testing ??&lt;/td&gt;
   &lt;td height="52" width="268"&gt;There are various
   Record/Playback/Scripted tools e.g. Selenium. Load Testing ?? (Script
   with HtmlUnit?)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00" height="30"&gt;Accessibility&lt;/td&gt;
   &lt;td height="30" width="269"&gt;Supports the W3C Initiative for
   Accessibility for Rich Internet Apps (WAI-RIA).&lt;/td&gt;
   &lt;td height="30" width="272"&gt;Supports Microsoft Active
   Accessibility (MSAA) for Internet Explorer.&lt;/td&gt;
   &lt;td height="30" width="266"&gt;None (custom build?)&lt;/td&gt;
   &lt;td height="30" width="270"&gt;Supports Microsoft Active
   Accessibility (MSAA) for Internet Explorer.&lt;/td&gt;
   &lt;td height="30" width="268"&gt;None (custom build?)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00"&gt;Printing&lt;/td&gt;
   &lt;td width="269"&gt;Can print as with HTML pages.&lt;/td&gt;
   &lt;td width="272"&gt;Can print with additional page setup.&lt;/td&gt;
   &lt;td width="266"&gt;Can print as with HTML pages.&lt;/td&gt;
   &lt;td width="270"&gt;Can print with additional page setup.&lt;/td&gt;
   &lt;td width="268"&gt;Can print as with HTML pages.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
   &lt;td width="118" bgcolor="#99CC00"&gt;Search Engine Optimization&lt;/td&gt;
   &lt;td width="269"&gt;Not directly compatible (embed host pages with
   search terms).&lt;/td&gt;
   &lt;td width="272"&gt;Not directly compatible (embed host pages with
   search terms).&lt;/td&gt;
   &lt;td width="266"&gt;Not directly compatible (embed host pages with
   search terms).&lt;/td&gt;
   &lt;td width="270"&gt;Not directly compatible (embed host pages with
   search terms).&lt;/td&gt;
   &lt;td width="268"&gt;Not directly compatible (embed host pages with
   search terms).&lt;/td&gt;
  &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-5599119693083425260?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/QctrWSKDl-AuhJfxrcA6bgvUT7w/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QctrWSKDl-AuhJfxrcA6bgvUT7w/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/QctrWSKDl-AuhJfxrcA6bgvUT7w/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/QctrWSKDl-AuhJfxrcA6bgvUT7w/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/RkfRGwWBk08" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/5599119693083425260/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=5599119693083425260" title="22 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/5599119693083425260?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/5599119693083425260?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/RkfRGwWBk08/comparing-ria-frameworks.html" title="Comparing RIA Frameworks" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><thr:total>22</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2009/02/comparing-ria-frameworks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EASHw7fyp7ImA9WxVXGU0.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-2633729296169554569</id><published>2009-02-17T10:55:00.001-08:00</published><updated>2009-02-17T14:27:29.207-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-17T14:27:29.207-08:00</app:edited><title>Issues with GWT</title><content type="html">&lt;p&gt;
Google Web Toolkit (GWT) is an AJAX based RIA framework that promises to enrich your Java/JEE Web Applications with a Rich user experience. It also promises to ease error-prone JavaScript &amp; HTML development by abstracting it under the safety of a compile-time language like Java. GWT is a good framework overall and delivers on most of its promises -but- a few short-comings are to be noted.
&lt;/p&gt;

&lt;p&gt;
Reviewer: Sony Mathew, GWT version 1.5&lt;br&gt;
&lt;/p&gt;

&lt;ol&gt;
 &lt;li&gt;
  &lt;h3&gt;Great Tool support but...&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;Being in Java all Java IDE tool support is available at your fingertips.&lt;/li&gt;   
   &lt;li&gt;Comes with a GWT Browser for immediate edit feedback but can be slow.&lt;/li&gt;
   &lt;li&gt;Debugging of client-side and server-side seamless in Eclipse.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Had to custom build:&lt;/u&gt; Eclipse plugin for compilation &amp; workspace Ant tasks.
  &lt;ul&gt;
   &lt;li&gt;May not need as better plugins come out.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
 &lt;/ol&gt; 
 &lt;/li&gt; 
 &lt;li&gt;
  &lt;h3&gt;UI Design in Java maybe cumbersome.&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;No Graphical designer (GWT Designer exists, haven't tried, its for pay &amp; don't expect much).&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Complex layouts can be easily abstracted into components and reused.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Complex HTML layouts and semi-static HTML snippets can be easily abstracted to Static-Content and reassembled dynamically.&lt;/li&gt;   
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Fluent interfaces like AxisPanel can be easily created to alleviate complex layouts&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Can purchase/obtain 3rd party rich components.&lt;/li&gt;   
  &lt;/ol&gt; 
 &lt;/li&gt; 
 &lt;li&gt;
  &lt;h3&gt;Compilation takes a while.&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;Don’t need to compile very often during dev.&lt;/li&gt;
   &lt;li&gt;Compile initially and when making changes to RPC transported
   beans.&lt;/li&gt;
   &lt;li&gt;View UI edits via GWT provided browser for changes.&lt;/li&gt;
  &lt;/ol&gt; 
 &lt;/li&gt;
 &lt;li&gt;
  &lt;h3&gt;Browser inconsistencies abstracted well but...&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;CSS inconsistencies still remain, All Widgets are CSS driven.&lt;/li&gt;
   &lt;li&gt;HTML/JavaScript inconsistencies abstracted well but custom components will require some hand-coding of HTML &amp;amp; JavaScript.&lt;/li&gt;
  &lt;/ol&gt; 
 &lt;/li&gt;    
 &lt;li&gt;
  &lt;h3&gt;Cannot style all areas of all Widgets.&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;E.g. parts of TabPanel.&lt;/li&gt;
  &lt;/ul&gt; 
 &lt;/li&gt; 
 &lt;li&gt;
  &lt;h3&gt;Java/JRE Emulation limitations&lt;/h3&gt;
  &lt;b&gt;Requires that classes be scrubbed of following  unsupported (non-compilable) references:&lt;/b&gt;  
  &lt;ol&gt;
  &lt;li&gt; 3rd Party classes:&lt;ul&gt;
   &lt;li&gt;e.g. org.apache.commons.*, org.hibernate.* etc.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Eliminate references.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Add source (.java) to classpath.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Use your own custom equivalents (e.g. custom ToStringBuilder).&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;BigDecimal:&lt;ul&gt;
   &lt;li&gt;Client-side
   BigDecimal math not supported because it is not performant.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Can use 3rd party 'gwt-math.jar'.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Redesign beans to use Money, inject appropriate  client/server side MoneyCalc.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;List.subList():&lt;ul&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Use an explicit for-loop to create a new list.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Object.clone():&lt;ul&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Use a Copy Constructor and set fields individually.
   &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt; 
  &lt;li&gt;java.util.Calendar, java.text.DateFormat (and subclasses) :&lt;ul&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Use deprecated java.util.Date constructors and methods.
   &lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Redesign beans to use java.util.Date, inject appropriate  client/server side Formatters.&lt;/li&gt;  
   &lt;/ul&gt;
  &lt;/li&gt;  
  &lt;li&gt;java.text.NumberFormat and java.text.*:&lt;ul&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Use GWT provided classes - not optimal unless on client
   side.&lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Redesign beans, inject  appropriate client/server side Formatters.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;  Misc RPC Serializing issues:&lt;ul&gt;
   &lt;li&gt;Doesn't serialize final fields.&lt;/li&gt;
   &lt;li&gt;HashMap: Make sure contents are serializable.&lt;/li&gt;
   &lt;li&gt;Old Style Enums require no-arg constructor and non-final
   fields.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;GWT Unit tests:
  &lt;ul&gt;
   &lt;li&gt;If present in same package can cause compile errors unless you scrub
   the tests: Including placing junit source on classpath.&lt;/li&gt;
   &lt;li&gt;Note: having different source folders will NOT help if .class
   files are compiled to same output location.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;/li&gt;         
  &lt;/ol&gt;
 &lt;/li&gt;   
 &lt;li&gt;
  &lt;h3&gt;Scrub Hibernate loaded beans of non-compilable references.&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;Only if loaded beans reference Hibernate classes such as HashSet,
   Session etc.
   &lt;/li&gt;
   &lt;li&gt;Only an issue for lazy-loaded associations &amp; collections
   (verified).
   &lt;ul&gt;
    &lt;li&gt;Hibernate beans with no lazy assocs were readily serialized.&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
    &lt;li&gt;&lt;u&gt;Fix:&lt;/u&gt; Hibernate.initialize() on all objects
   &lt;ul&gt;
    &lt;li&gt;May not be sufficient - verify.&lt;/li&gt;
   &lt;/ul&gt;
   &lt;/li&gt;
   &lt;li&gt;&lt;u&gt;Fix&lt;/u&gt;: Deep Copy beans:
   &lt;ol&gt;
    &lt;li&gt;Manual Copy Constructors on beans.&lt;/li&gt;
    &lt;li&gt;Use automated reflection based copy (including for collections).
   &lt;/li&gt;
   &lt;/ol&gt;
   &lt;/li&gt;
  &lt;/ol&gt; 
 &lt;/li&gt; 
 &lt;li&gt;
  &lt;h3&gt;Can use server-side classes on client-side but...&lt;/h3&gt;
  &lt;ol&gt;
   &lt;li&gt;Requires a “gwt.xml” file in referenced Java package (2 lines).&lt;/li&gt;
   &lt;li&gt;May require scrubbing of non-compilable references.&lt;/li&gt;
   &lt;li&gt;May require scrubbing of Hibernate loaded beans for RPC serialization&lt;/li&gt;   
  &lt;/ol&gt; 
 &lt;/li&gt; 
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-2633729296169554569?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Bqe2ZYyl5yyXcgEQI4uMz8lgG5g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bqe2ZYyl5yyXcgEQI4uMz8lgG5g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Bqe2ZYyl5yyXcgEQI4uMz8lgG5g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Bqe2ZYyl5yyXcgEQI4uMz8lgG5g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/f2DRe153B5A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/2633729296169554569/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=2633729296169554569" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2633729296169554569?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/2633729296169554569?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/f2DRe153B5A/issues-with-gwt_17.html" title="Issues with GWT" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><thr:total>3</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2009/02/issues-with-gwt_17.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcNRXwyeyp7ImA9WxVXGEQ.&quot;"><id>tag:blogger.com,1999:blog-5023668331319058505.post-4094905341389303730</id><published>2008-12-03T11:12:00.001-08:00</published><updated>2009-02-17T10:41:34.293-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-17T10:41:34.293-08:00</app:edited><title>Fluent DSL for Rich-UI</title><content type="html">&lt;div style="text-align: left;"&gt;User Interface (UI) Layouts are generally defined using declarative forms such   as HTML or XML.  One of the primary reasons for this is to separate roles   of UI designers and programmers - whether they are separate individuals or the   same person.  However, this separation is going to reach its practical   limits as user experience requirements get richer and more demanding - what I   mean is - an XML or HTML template is just NOT going to be a valid   representation of the view that the user sees because at the end of the day   its just a static view.  A richer experience by definition means the view   is changing constantly with each user action - sometimes drastically - this   means the code behind the template will become the center of focus as it   re-shapes the view in response to user actions.  As for XML or HTML   templates - well they can continue to have a place subordinate to the UI code,   loaded on demand perhaps for small fixed layout sections and like its cousin   "the image" banished to the static content-managed realm.  Additionally,   code close to the UI will be managing more data, state transitions and   controller logic for quicker user responses.  People who demand a   "staticky" template-first approach for UI design will end up with an   increasingly complex soup of code mixed inside an increasingly irrelevant and   inaccurate template - creating something that neither the UI designers nor   programmers can consume easily with their minds or their tools.   It   will become more practical in the future for programmers to develop the UI   using a programming language from a set of mock-ups created by the UI   designers - to fully deliver the dynamic user experience desired.

However, building UI in programming languages can be verbose and cumbersome   with little clarity and virtually no visual clues to the layout structure in   the code. This needs to be fixed - and it can be fixed by heavily leveraging   Object-Oriented features - in fact with the right approach OO languages like   Java can provide a truly great experience for laying out complex UI for Rich   Internet Apps (RIA) (not to mention for Desktop Apps or even today's   old-fashioned static HTML generating web apps).   UI Building in an OO   language can be made fluent and succinct such that it can &lt;u&gt;out-do&lt;/u&gt; any   equivalent HTML/XML format in simplicity, clarity and functionality.    Unlike external DSLs that exist today - I would prefer a DSL internal to my   native programming language for building my UI.  A DSL internal to your   native language simplifies the transition you undoubtedly must make between   your UI and its supporting data models, controls and services written in your   native language - not to mention being able to use your favorite language   tools like code-refactoring.  Now I am not suggesting that all UI   frameworks in the future should support a single Fluent API (or be written   only in Java) but if enough DSLs start looking similar - a standard should be   considered for your favorite programming language and adopted by the web   frameworks supporting that language.

&lt;/div&gt; The terms Fluent and DSL are in reference to Martin Fowler's writings.  I won't go into detail regarding them.&lt;span class="fixed_width"  style="font-family:Courier,Monospaced;"&gt;&lt;span style="font-family:Verdana;"&gt;  Checkout Martin Fowler's entries &lt;a href="http://www.martinfowler.com/bliki/DomainSpecificLanguage.html" id="spei" title="DomainSpecificLanguage (DSL)"&gt;DomainSpecificLanguage (DSL)&lt;/a&gt; and &lt;a href="http://www.martinfowler.com/bliki/FluentInterface.html" id="ff20" title="FluentInterface"&gt;FluentInterface&lt;/a&gt;.

&lt;/span&gt;&lt;/span&gt; &lt;h2&gt;&lt;b&gt;AxisPanel&lt;/b&gt;: &lt;b&gt;An example&lt;/b&gt;&lt;/h2&gt; Lets look at an example of a fluent layout panel I created in Java called AxisPanel.  I created this primarily for GWT but I've also created a sample panel for Swing, and conceivably such a Fluent API could also be created for generating old-fashioned static HTML on the server-side (imagine &lt;u&gt;NOT&lt;/u&gt; having to deal with untyped ${expression} anymore).  The AxisPanel API attempts to follow the elegant principle of self-similarity (a property of &lt;a href="http://en.wikipedia.org/wiki/Fractal" id="lf2w" title="Fractals"&gt;Fractals&lt;/a&gt;) such that complex layouts are created with a few simple constructs applied recursively.   AxisPanel lays your widgets out in the X axis (horizontal) or Y axis (vertical), you can nest as deep as you like and set properties for any panel at any depth, and the important part is: you can modify your layout at any nesting depth simply by adding/removing x or y panels - you don't need to create new wrapper panels, find suitable variable names for each of them, or refactor insertion points of old panels every-time you change your mind as to where widgets are positioned.  This combination of horizontal and vertical layouts along with the fluent interface creates a very effective and powerful DSL in Java for laying out UI of almost any complexity.

Here is an example of using AxisPanel to emulate a simple Border Layout i.e. laying out widgets in a North, South, East and West fashion.
&lt;pre&gt;&lt;code&gt;AxisPanel p = new AxisPanel()
.y().width("100%")
    .x(myNorthContentPanel).css("north"&lt;/code&gt;&lt;code&gt;).q()
    .x().width("100%")
        .y(myWestContentPanel).css("west").q()
        .y(myCenterContentPanel).css("center")
            .width("100%").align(0,0).q()
        .y(myEastContentPanel).css("east")
            .width("100%").align(1,0).q()
        .q()
    .x(mySouthContentPanel).css("south").q()
    .q();
&lt;/code&gt;&lt;/pre&gt; 
Where:
x(...) - Add widgets horizontally.
y(...) - Add widgets vertically.
q() - Quit building the current panel and revert to building the parent panel.
css(..), width(..), etc. - various properties that can be set on any panel.

Note: The various content panels (e.g. myNorthContentPanel) could have been created in-line recursively as well, but to emphasize the Border Layout they are shown as created earlier (perhaps as other AxisPanels).

&lt;h2&gt;   &lt;b&gt;AxisPanel: Another example&lt;/b&gt; &lt;/h2&gt; The following example lays out a series of search options on the top half of the page followed by a dynamic bottom section that changes based on the search performed i.e. results section.  The results section has a results table and a cart - and users can move items between the results and the cart real-time.  This example shows the layout only - the interactive widgets like buttons, links, text-boxes along with their action listeners were created prior to their layout (as I layout and find I need a button or a text-box,  I create them just above the layout or in another  dedicated method).
&lt;pre&gt;&lt;code&gt;AxisPanel p = new AxisPanel()
.y().css("search").border(1)
    .y().css("options").space(5)
        .x("Search Options").css("header").space(5).q()
        .x(searchByNameOption,searchByNameBox).css("byName").space(5)
            .x(alphaLinks).css("alpha-links").space(5).q()
            .q()
        .x(searchTop10Option, searchTop10Box).css("top10").space(5).q()
        .x(searchButton).space(5).q()
        .q()
    .y().css("results").width("100%").space(5)
        .y().css("info").space(5)
            .x("Search Results").css("header").q()
            .x("Click Cart+ to move items to cart")
                .css("howto").q()
            .q()
        .x().space(20).width("80%").align(0,0)
            .y().css("detail")
                .x("Your Results").css("header").q()
                .x(searchResultsTable).css("table").border(1).q()
                .x(pagePrevLink, new Label("page"), pageNextLink)
                    .space(5).width("100%").align(0,0).q()
                .q()
            .x(new Image("/path/to/a&lt;/code&gt;&lt;code&gt;rrow/image")).q()
            .y().css("cart")
                .x("Your Cart").css("header").q()
                .x(itemCartTable).css("table").border(1).q()
                .x(itemCartRemoveAllLink).space(5).width("100%")
                    .align(0,0).q()
                .q()
            .q()
        .x(checkOutButton).width("80%").q()
        .q()
    .q();
&lt;/code&gt;&lt;/pre&gt;
&lt;span style="font-style: italic;"&gt;Here is the result of the above sample layout:&lt;/span&gt;

&lt;div style="width:650px; height:300px;"&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_8RRgWmgmc1E/STl1Biv6RTI/AAAAAAAAAQA/DzfF1EFY3as/s1600-h/AxisPanelDemo-Search.JPG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 230px;" src="http://4.bp.blogspot.com/_8RRgWmgmc1E/STl1Biv6RTI/AAAAAAAAAQA/DzfF1EFY3as/s320/AxisPanelDemo-Search.JPG" alt="" id="BLOGGER_PHOTO_ID_5276377107809322290" border="0" /&gt;&lt;/a&gt;
&lt;/div&gt;

&lt;h2&gt;&lt;b&gt;In conclusion&lt;/b&gt;: &lt;/h2&gt;  Hopefully, the AxisPanel example demonstrates that you can create a Fluent Object-Oriented DSL within your native language that is simpler yet more powerful than its declarative XML/HTML cousins for coding Rich Internet Apps (RIA) (in addition to Desktop Apps or even old-fashioned static HTML generating apps).  Without a Fluent API, complex layouts in your native language can be verbose with unclear layout structures and cumbersome modifications.  AxisPanel is a good start but I would like to see more Fluent APIs in Java and other OO languages coming out of the wood-work and supported by more web-frameworks directly.

See sample AxisPanel code:
&lt;a href="http://code.google.com/p/xsonymathew/wiki/AxisPanel" id="yq96" title="http://code.google.com/p/xsonymathew/wiki/AxisPanel"&gt;http://code.google.com/p/xsonymathew/wiki/AxisPanel&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5023668331319058505-4094905341389303730?l=sonymathew.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/s46g4ACeNL734QkBgJpiGFdQf1o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s46g4ACeNL734QkBgJpiGFdQf1o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/s46g4ACeNL734QkBgJpiGFdQf1o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/s46g4ACeNL734QkBgJpiGFdQf1o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/SignOfTheTimes/~4/8ndnoW9NYN0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sonymathew.blogspot.com/feeds/4094905341389303730/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=5023668331319058505&amp;postID=4094905341389303730" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/4094905341389303730?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5023668331319058505/posts/default/4094905341389303730?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/SignOfTheTimes/~3/8ndnoW9NYN0/fluent-dsl-for-rich-ui.html" title="Fluent DSL for Rich-UI" /><author><name>Sony Mathew</name><uri>http://www.blogger.com/profile/00345410246622289203</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="24" src="http://2.bp.blogspot.com/_8RRgWmgmc1E/S3wcHWQecrI/AAAAAAAAAZU/XDCgyOs4qGU/S220/DSC00315.JPG" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_8RRgWmgmc1E/STl1Biv6RTI/AAAAAAAAAQA/DzfF1EFY3as/s72-c/AxisPanelDemo-Search.JPG" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://sonymathew.blogspot.com/2008/12/fluent-dsl-for-rich-ui.html</feedburner:origLink></entry></feed>

