Enterprise Flex, , " />

FlashPlatformist
Articles, Information, News, & Tutorials for Adobe Flash Platform Developers and Architects

Enterprise Flex and the Swiz Framework Architecture, Part 3: Using Autowire and Mediate

In the last entry on the Swiz framework architecture, we took a look into the use of the CentralDispatcher. More specifically, we looked at the middle section of the following architectural diagram that I designed to help Swiz make more sense for developers. In this entry, we will get into the upper portion of the diagram, the real meat of the framework – Autowire and Mediate.

Architectural Diagram of the Swiz Framework

Architectural Diagram of the Swiz Framework

In declarative languages such as ActionScript, an object is created by declaring it and assigning the instance of that object to a variable using the new keyword. This has proven to be problematic in larger applications because of it’s “top-down” approach to object instantiation, which results in “tight coupling” (dependencies between otherwise independent objects) among other things.

In contrast, the Inversion of Control pattern used by Swiz reverses this object instantiation process by creating and implementing objects at application runtime. This eliminates dependencies and increases loose coupling because the implementation is created dynamically, as you are about to see.

The Swiz framework solves this problem rather inventively, through the use of two primary facets: the Swiz BeanLoader object and custom meta data tags. The Autowire tag is used for component wiring, while the Mediate tag is used for dynamic mediation of events during the bubbling phase of the event life cycle. These meta data tags are added to the framework simply by adding the following to the compiler settings in the Flex project properties panel:

-keep-as3-metadata +=Autowire,Mediate

Promote Loose Coupling with Autowire

Placing the Autowire meta data above the property of an object tells Swiz that it should inject a specified property from another class into this property, as seen in Listing 1.

Code Listing 1. Using the Autowire meta data tag

[Autowire( bean="displayRoot", property="currentView", twoWay="true" )]
[Bindable]
public var currentView:String;

You may have noticed three additional properties that immediately follow the Autowire declaration: bean, property, and twoWay. A bean represents an object that has been declared within a Swiz BeanLoader object; which brings us to…

The Swiz BeanLoader Object

Swiz does a superb job of separating the view from business logic. The concept of Beans and BeanLoaders are well known in Java GUI development circles, but have never been used before in application development for the Flash Platform. The result is a noticeable improvement in code organization, as well as the realization of a simple and clearly defined application life cycle.

A Swiz BeanLoader is an MXML file that acts similar to an object registry. When you create a bean loader, you’re extending the Swiz BeanLoader class, which registers the objects that you want Swiz to manage, as seen in Code Listing 2.

Code Listing 2. Example of a Swiz BeanLoader

 <?xml version="1.0" encoding="utf-8"?>
<BeanLoader xmlns="org.swizframework.util.*" xmlns:view="com.danorlando.view.*">
 <view:DisplayRoot id="displayRoot"/>
 <view:StatsView id="statsView"/>
 <view:VideoView id="videoView"/>
</BeanLoader>

The property value that is declared after the Autowire meta data pertains to the currentView variable in the displayRoot bean. Since the currentView property in code listing 1 and the respective currentView property that is found in the displayRoot bean are both marked accordingly, Swiz will create a binding between them to ensure that changes that occur to currentView in DisplayRoot are also propogated to the currentView property found in the component that holds the code found in listing 1 above. If that seemed like a lot to swallow, go through it a few times, this time taking it in bite-size chunks. This is one of the most important parts of Swiz, and has allowed me to do things with Flex and ActionScript that would otherwise be impossible.

The last property that is available with the Autowire meta data, called twoWay, is capable of setting up a reverse propagation in the other direction when set to true. In other words, the currentView property in the displayRoot bean will be updated if the currentView property in the component changes.

Save Time and Eliminate Repetitive Code with Dynamic Mediation

If you are already familiar with what a publish-subscribe design pattern is, then understanding dynamic mediation should be a piece of cake. To initialize dynamic mediation, the second Swiz meta data is used, called Mediate. Code listing 3 demonstrates the use of the Mediate meta data key word.

Listing 3. Using dynamic mediation in Swiz with the Mediate meta data key word

[Mediate( event="DataEvent.SHOW_DATATIP", properties="index,data" )]
public function showDataTip( index:int, data:ArrayCollection ):void {
   var itemData:String = data.getItemAtIndex(index).toString;
   var dataTip:DataTip = new DataTip(itemData);
   addChild(dataTip);
}

In the example demonstrated in listing 3, Swiz is always listening for the DataEvent.SHOW_DATATIP event. This happens by binding the event to the method with Mediate. When the event is fired, Swiz automatically runs the method. It is noteworthy to point out however, that in order to declare the event class and type as shown in code listing 3, the respective package containing the event must be registered in the eventPackages configuration setting where <SwizConfig /> is declared in the main application file.

The greatest benefit of dynamic mediation is essentially the same as that which is gained from dependency injection and Autowire meta data. Objects do not have to have any knowledge about each other or the application for which they reside. Not only does this make unit testing ridiculously easy for the application, it takes the concept of “code reuse” to a whole new level.

To see the implementation of Swiz into an actual application, check out Ben Clinkinbeard’s post HERE.

Possibly Related Posts:



Posted by Dan Orlando on August 24th, 2009 :: Filed under General
Tags :: , ,

Architectural Analysis of the Swiz Framework, Part 2: Central Event Control

In this segment, we will analyze how Swiz handles events, and how to utilize this feature of Swiz in an enterprise level application. Before moving any further however, here is the “more advanced version” of the Swiz architectural diagram I created for Linux magazine once again:

Architectural Diagram of the Swiz Framework

Architectural Diagram of the Swiz Framework

In the diagram, the Bean Factory represents a pool of MXML Beans that extend the Swiz BeanLoader class. As stated in Part 1 of this series, the purpose of Beans is simply to declare objects that will be used in the application and to assign IDs to them so they can be referenced by name later when they are autowired. The interesting thing about Swiz is that when it does its introspection on the BeanLoader, it instantiates all of the objects and creates a pool, or “factory”, where the objects are handed over on demand. For larger applications, this could potentially result in a very slightly extended load time, but the benefit is immeasurable because the result is that the application runs noticeably smoother and considerably faster.

In order to simulate a somewhat larger-scale application, the diagram displays four beans, which have only been separated as a matter of convenience. In essence, beans hold a strong resemblance to object registries, especially when you consider that you are essentially registering the objects declared in the beans to be managed by Swiz.

Swiz includes a class called the CentralDispatcher, which can be accessed directly through the Swiz.as class. The CentralDispatcher extends the Flex EventDispatcher and implements a Singleton pattern. I refer to this class as the “Event Bus” because it is a centralized place in which all events can be fired from.  This makes things nice and easy for managing the code base. Consider the following example:

  1. In the main application MXML file, set an event handler on the applicationComplete event of <mx:Application/>, like so:
    applicationComplete="applicationCompleteHandler(event)"
  2. Place the following code in the event handler function:
    protected function applicationCompleteHandler(event:FlexEvent):void {
         var del:XMLParserUtil = new XMLParserUtil();
         uiController.delegate = del;
         Swiz.addEventListener(DataReadyEvent.CORE_READY, setDataProviders);
    }
  3. Create a controller class that extends the Swiz AbstractController. Here is an example:
    package com.danorlando.controller
    {
       import com.danorlando.controller.events.DataReadyEvent;
       import com.danorlando.model.Globals;
       import com.danorlando.model.MediaObject;
       import com.danorlando.model.ViewStackDataCollectionObject;
       import com.danorlando.util.XMLFactory;
       import com.danorlando.util.XMLParserUtil;
       import mx.collections.ArrayCollection;
       import org.swizframework.Swiz;
       import org.swizframework.controller.AbstractController;
    
       public class UIController extends AbstractController
       {
          public static const GLOBAL_SETTINGS:String = "config/globals.xml";
    
          private var _mediaDP1:ArrayCollection = new ArrayCollection();
          private var _mediaDP2:ArrayCollection = new ArrayCollection();
          private var _mediaDP3:ArrayCollection = new ArrayCollection();
          private var _globals:Globals;
          private var _delegate:XMLParserUtil;
    
          //getters
          public function get mediaDP1():ArrayCollection { return _mediaDP1 }
          public function get mediaDP2():ArrayCollection { return _mediaDP2 }
          public function get mediaDP3():ArrayCollection { return _mediaDP3 }
          public function get delegate():XMLParserUtil { return _delegate }
          public function get globals():Globals { return _globals }
    
          //setters
          public function set mediaDP1(ac:ArrayCollection):void { _mediaDP1 = ac }
          public function set mediaDP2(ac:ArrayCollection):void { _mediaDP2 = ac }
          public function set mediaDP3(ac:ArrayCollection):void { _mediaDP3 = ac } 
    
          [Autowire]
          public function set delegate(del:XMLParserUtil):void {
             _delegate = del
             XMLFactory.parseXML(GLOBAL_SETTINGS, _delegate.parseGlobalSettingsXML);
      // listening to the Swiz event bus for GLOBALS_READY, which informs the controller
             // that the global config file has been parsed and loaded...
             Swiz.addEventListener(DataReadyEvent.GLOBALS_READY, initGlobals);
          }
    
          public function UIController()
          {
             _globals = Globals.getInstance();
          }
    
          protected function initGlobals(event:DataReadyEvent):void {
             var dbpath:String = _globals.mediaDatabasePath + _globals.mediaDatabaseFile;
             XMLFactory.parseXML(dbpath, _delegate.parseMediaDatabaseXML);
             // listening for DATA_READY, which will be fired when the media database has been loaded
             Swiz.addEventListener(DataReadyEvent.DATA_READY, delegateData);
          }
    
          protected function delegateData(event:DataReadyEvent):void {
             if (event.collection == null) {
                throw new Error("NO MEDIA COLLECTION!"); return;
             }
             var data:ArrayCollection = event.collection;
             for each(var o:Object in data) {
             var obj:ViewStackDataCollectionObject = o as ViewStackDataCollectionObject;
             var name:String = obj.name;
             var coll:ArrayCollection = obj.collection;
             if (name == "Video Production") {
                for each(var ob1:Object in coll) {
                   var mo1:MediaObject = ob1 as MediaObject;
                   _mediaDP1.addItem(mo1);
                }
             }
             else if (name == "Video Art") {
                for each(var ob2:Object in coll) {
                   var mo2:MediaObject = ob2 as MediaObject;
                   _mediaDP2.addItem(mo2);
                }
             }
             else if (name == "Music Production") {
                for each(var ob3:Object in coll) {
                   var mo3:MediaObject = ob3 as MediaObject;
                   _mediaDP3.addItem(mo3);
                }
             }
          }
          // the main application class is listening for CORE_READY, which essentially
          // lets the application know that the data has been loaded and is ready to
          // be used. Again, the Swiz event bus is used as a way of keeping things
          // tidy and under control by ensuring that events aren't firing all over the place.
          Swiz.dispatchEvent(new DataReadyEvent(DataReadyEvent.CORE_READY));
        }
      }
    }
  4. The final piece of the equation is the XMLParserUtil, which fires two events through the Swiz event bus, GLOBALS_READY and DATA_READY, as seen in the following code:
    package com.danorlando.util
    {
       import com.danorlando.controller.events.DataReadyEvent;
       import com.danorlando.model.Globals;
       import com.danorlando.model.MediaObject;
       import com.danorlando.model.ViewStackDataCollectionObject;
       import mx.collections.ArrayCollection;
       import mx.core.IUIComponent;
       import org.swizframework.Swiz;
    
       public class XMLParserUtil
       {
          public function XMLParserUtil() { }
    
          public function parseGlobalSettingsXML(xml:XML):void {
             var globals:Globals = Globals.getInstance();
             globals.mediaDatabasePath = xml.mediaDatabasePath;
             globals.mediaDatabaseFile = xml.mediaDatabaseFile;
             globals.mediaBaseUrl = xml.mediaBaseUrl;
             globals.contentPath = xml.contentPath;
             globals.thumbsPath = xml.thumbsPath;
            // firing the event through Swiz to let the controller know that
             // the global configuration info is ready
             Swiz.dispatchEvent(new DataReadyEvent(DataReadyEvent.GLOBALS_READY));
          }
    
          public function parseMediaDatabaseXML( db:XML ):void {
             var mediaCollection:ArrayCollection = new ArrayCollection();
             for each(var x:XML in db..view) {
                var collObj:ViewStackDataCollectionObject = new ViewStackDataCollectionObject();
                collObj.id = x..@id;
                collObj.name = x..@name;
    	    for(var i:Number = 0 ; i < x.children().length(); i++) {
                   var obj:MediaObject = new MediaObject()
                   obj.type = x..mimetype[i];
                   obj.file = x..file[i];
                   obj.thumb = x..thumb[i];
                   obj.title = x..title[i];
                   obj.description = x..description[i];
                   obj.credits = x..credits[i];
                   collObj.collection.addItem( obj );
                }
               mediaCollection.addItem(collObj);
             }
           // creating a DATA_READY event and firing it through the Swiz event bus;
             // the data collection is sent along with the event when it is dispatched.
             var evt:DataReadyEvent = new DataReadyEvent(DataReadyEvent.DATA_READY);
             evt.collection = mediaCollection;
             Swiz.dispatchEvent(evt);
          }
       }
    }

The important thing here is to pay attention to the event flow between the main application file, the controller class, and the business delegate. The advantage of structuring it like this is that by centralizing the event flow, you maintain a higher level of control over what is happening and when it happens within the application. It also keeps things a lot tidier, which becomes more noticeable as the application grows.

Stay tuned for the final part to my series on the Swiz framework, where we’ll discuss the best part of the framework – autowiring.

Additionally, my article on Swiz should be published shortly by Linux magazine, in which case I will post that link here as well.

Possibly Related Posts:



Posted by Dan Orlando on May 16th, 2009 :: Filed under General
Tags :: , ,

Flex in the Enterprise: Architectural Analysis of the Swiz Framework, Part 1

I’ve spent an incredible amount of time recently working with the new Swiz framework for my latest article, which will be published soon by Linux Magazine.  Since Swiz is so new, and in consideration of the fact that very few developers even know what it is, the article was more of an “introduction to Swiz” type of article. However, as a result of the immense amount of time that I’ve spent analyzing the code and speaking with the developers, Chris Scott and Soenke Rohde, I decided to provide a more advanced architectural analysis of the framework here. If you are new to Swiz, my suggestion is to first read the introductory materials that are provided, or this article might make your head spin. I do not expect Linux to publish the article I wrote for them for at least another week, so if you need a basic introduction to the Swiz framework, I suggest taking a look at the project’s wiki on Google Code. For an excellent tutorial on creating a project with the Swiz framework, I strongly suggest taking a look at this five-part series written by Brian Koteck.

Swiz Architecture

I wanted to create a diagram to support the content of the article I was writing for Linux Magazine. However, what I ended up with was much more complex than I had intended. As a result, I created a simplified diagram for the article as a way of visualizing the application life cycle, and decided to post my original diagram here, which provides a visual depiction of both the behavior of Swiz, as well as its architecture. The diagram is shown in Figure 1. Note that you may click on the image to bring up a much larger version in another window. Viewing it that way may make it easier to comprehend as your read the following description.

5,000-foot View of the Architecture and Behavioral Foundation of Swiz

Figure 1: 5,000-foot View of the Architecture and Behavioral Foundation of Swiz

Go with the Flow

The main application file is identified by the purple shape in the diagram with the text “Default Application”. In most Flex applications, this is usually an MXML file that extends Application or WindowedApplication. Note that projects that are purely ActionScript will not be able to take complete advantage of the features of the Flex framework. You will see why in just a bit. Swiz is fired up on the preinitialize event during application initialization, which initiates what I refer to in the diagram as the “Life Cycle Manager”.  Currently, the Swiz.as class in the framework acts as both the life cycle manager and what I refer to as the “Event Bus” in the diagram. However, this will change soon, where Swiz.as will be used for global variables. The loadBeans method is what starts up the Swiz “introspection engine”, so the Life Cycle Manager can be identified by the class that the loadBeans method is called on. My guess is that this method will not move from Swiz.as, and if it does move to a separate “LifecycleManager” class, the method will still be accessible from Swiz.as.

See, the core methodology of Swiz is to maximize simplicity, and that is why we have microarchitectures and design patterns in the first place. The problem is that not every architect understands this. Often we find architectures and design patterns being used in ways that do nothing more than increase complexity, which is totally counter-intuitive. Initializing Swiz simply by calling Swiz.loadBeans is incredibly simple. That is why I suspect that even if the method is moved to a full-blown LifeCycleManager class, you will still be able to initialize Swiz by simply calling Swiz.loadBeans.

What is a Bean?

Beans in Swiz are MXML files that extend the Swiz BeanLoader class. Within the BeanLoader tags, you have a series of object declarations. Figure 2 demonstrates what this might look like for a delegates bean.

 <?xml version="1.0" encoding="utf-8"?>
<BeanLoader xmlns="org.swizframework.util.*" xmlns:del="com.danorlando.delegates.*">
   <del:UserCrudDelegate id="userCrudDelegate"/>
   <del:StatsCrudDelegate id="statsCrudDelegate"/>
   <del:VideoCrudDelegate id="videoCrudDelegate"/>
</BeanLoader>

Figure 2: In this hypothetical example, the delegates for basic CRUD operations on users, stats, and videos are registered in a file called DelegatesBean.mxml.

The Introspection Engine

Now that you have seen what a sample bean looks like, its easier to understand that when the introspection engine runs, it looks at all objects that have been registered within BeanLoader classes and the BeanFactory creates and holds instances of the objects to be wired up next. In the Figure 1 diagram, I am showing a hypthetical example where four BeanLoaders have been iterated and pooled in the BeanFactory in four categories: Services, Components, Data Model, and Commands.

In the next installment, we will go in depth in the upper half of the diagram and discuss autowiring and the Event model.

Possibly Related Posts:



Posted by Dan Orlando on May 1st, 2009 :: Filed under General
Tags :: ,

Could Swiz be the Best Micro-architecture for Enterprise Flex Applications?

It has been four years since Adobe Flex 1.0 was released. Since then, many API’s, libraries, and frameworks have been released, most of which have been open source.  There is one key facet that is central to the evolution of any programming language, and when it comes to Adobe Flex, this important element required for mass adoption of the framework has been severely neglected; architectural frameworks for the enterprise. See, in order for a programming language to receive mass adoption, it must be capable of supporting enterprise grade applications, which by their very nature, often consist of millions of lines of code. For 4 years, enterprise Flex and AIR developers had only two choices of microarchitecture: Cairngorm and PureMVC; both of which fell far short of being viable solutions for the enterprise. It is for this reason that despite extensive efforts, Adobe has struggled – and in many cases failed – to effectively inject Flex into the enterprise space. The common response from enterprise executives has been that it is “unproven technology”.

A technology is usually characterized as “unproven” when it lacks the ability to fulfill the unique needs of enterprise application development. There has been a lot of talk about the number of enterprise application projects that have recently failed miserably, costing the company a lot of company (and some companies to go under) as a result of not having the right tools to meet the needs of application development in the enterprise.

Recently, a brilliant man by the name of Chris Scott released a framework on Google Code, which he developed to solve this problem. He called his framework “Swiz”.  Not surprisingly, very few people are aware that this architectural framework even exists. This framework advances RIA development by escalating the viability of Flex in the enterprise ten-fold.  It does so by taking a different approach than the alternatives. Instead of force-fitting J2EE design patterns into the event-driven Flex framework, Swiz uses the Inversion of Control pattern, which put very simply: reverses the “wiring” of dependent objects within the application.

After listening to podcast interviews and reading through Chris’ blog, he is clearly thinking along the same lines as a lot of us right now who have been unhappy with the set of choices available for Flex micro-architecture frameworks. It was refreshing to find Swiz, as I had taken on the endeavor of constructing my own micro-architecture which coincidentally modeled Swiz very closely. And yet, Swiz is a whole lot farther along than I was. What is amazing to me is how this just sort of popped up out of nowhere. I consider this a major advancement in Flex and AIR enterprise development.

Additional Information

The framework is open source on Google code here:
http://code.google.com/p/swizframework/

Additionally, a very useful article on Swiz was published on InsideRIA here:
http://www.insideria.com/2008/12/frameworkquest-2008-part-4-ioc.html

Chris’ blog can be found here:
http://cdscott.blogspot.com/

A podcast interview with Chris explaining the underlying concepts and why he created Swiz:
http://www.theflexshow.com/blog/index.cfm/2008/6/19/The-Flex-Show–Episode-45-Interview-with-Chris-Scott-talking-about-the-Swiz-Framework

Possibly Related Posts:



Posted by Dan Orlando on April 27th, 2009 :: Filed under General
Tags :: , , , ,

Understanding Flex Communication Protocols

Developing enterprise applications with Flex or AIR often requires a paradigm shift, regardless of your development background.  For web developers, it is the shift from stateless development to stateful. For Flash designers and AS2 developers, it is the painful realization that most of your programming up to this point hasn’t exactly been what is commonly referred to as “object-oriented” and a steep learning curve may lie ahead. For Java developers, it is the fact that although ActionScript 3.0 sometimes looks much like Java, this can be deceiving when developing enterprise applications with Flex and AIR.

For all intents and purposes, this article should serve as an informative resource for both Flex developers and technical business managers.  The goal is to provide a high-level view of enterprise Flex and AIR development, and assist with a global understanding of the technologies involved and when they should and should not be used.


Client-Server Communication

Choosing a server side language and communication method with Flex and AIR depend largely on facets of the business that are rarely taken into consideration by most developers. Usually, the technical decision-makers or lead architect will choose the technology that she knows best. This sometimes leads to disastrous results. The key to success here is to focus on the business model, and the tool will present itself.


Language doesn’t matter

While each server side platform has it’s own costs and benefits to the business; the Flash Virtual Machine really doesn’t care what is running on the server side. All it cares about is how the data is served up and whether or not it needs to deserialize it.  In fact, the FVM is usually completely unaware of what is running on the server side, especially if it is aggregating data from multiple sources.  That is the beauty of the separation between the server side business logic and the client side application that runs on the desktop or within the browser.  With that said, it is more practical to discuss method of communication.


Action Message Format (AMF)

The Action Message Format (hereafter referred to as “AMF”) is the binary data protocol officially supported by the Flash Virtual Machine. In other words, Serialization and Deserialization (otherwise known as marshalling and unmarshalling) of data objects is already built into – and is easily handled by – the Flash VM during runtime. AMF can be best described as a SOAP-RPC hybrid, in which data is transferred via Remote Procedure Calls. It is hard to place AMF in its own category here since it is really nothing more than an RPC protocol. However, the fact that it is the protocol officially supported by Adobe for client-server communications, and has built-in support with the Flash Virtual Machine makes it worth placing in its own category.

Advantages of AMF include: rapid data transfer, automatic marshalling and unmarshalling of data objects by the FVM, support across the entire spectrum of server side languages including .NET, PHP, Java, Ruby, and Python.

Disadvantages of AMF include: proprietary protocol that is not compatible with other client-side RIA development platforms such as DOJO, Scriptaculous, and SilverLight.  However, JavaScript communication via AMF with a server language is made possible through the Adobe AIR platform.
Requirements: Integration is fast and simple, and is made possible by integrating one of the following frameworks into your respective server environment:
PHP:  Zend, AMFPHP,  WebOrb for PHP, SabreAMF
Java: BlazeDS, Red5, GraniteDS, WebOrb for Java
.Net: FluorineFx, WebOrb for .Net, AMF.NET
Python: PyAMF
Ruby on Rails: RubyAMF, WebOrb for Ruby on Rails

Representational State Transfer (REST)

REST is built on simple http. However, support for RESTful services in Flex 3 is limited. Therefore, you will need to use either BlazeDS or a proxy in order to extend the Flex functionality for RESTful services beyond GET and POST.

Advantages include: direct communication with xml data sources, useful for web syndication

Disadvantages include: it is slow in comparison to the AMF protocol


SOAP, WSDL, RPC, and Everything Else

Most communication protocols (AMF included) are really just a REST-RPC hybrid that uses the http protocol in some way for request-response transfers. These types of communications are usually accomplished by simply calling a specific URI via the HTTPService class in Flex.

Possibly Related Posts:



Posted by Dan Orlando on March 31st, 2009 :: Filed under Enterprise Flex, Tutorials
Tags :: , , , ,

Enterprise Flex Model – v0.3

Version 0.3 of my new Flex enterprise development model got quite an overhaul. For those who are not familiar with the background of this posting, I am on an endeavor to create an alternative to Cairngorm and PureMVC for enterprise Flex/AS3 application architectures; particularly one which caters specifically to the Flex framework and is not based purely on J2EE best practices. A few points worth noting that I have yet to point out with this architecture:

The UIController

The UIController is meant to be a singleton class that provides access to the central event dispatcher (the event bus), as well as the model, which would likely be a getter for a centralized model class in the business library, which then has getters and setters for all the value objects contained in the model package. The UIController would be instantiated by the LifeCycleManager class, which would also have the responsibility of determining the application’s initial state (for example, if credentials are already in the encrypted local store and can be validated, go straight into the app without asking for credentials). The lifecycle manager also waits for a “MODEL_INITIALIZED” type of event, letting it know that any of the necessary client-server communications required prior to display of the initial application state are completed, at which point it instantiates the UIController. The UIController would also contain a command called something like “setBindings”, which would iterate through the bindingDictionaries package and set the bindings accordingly. With regard to this method of setting bindings, I still haven’t figured out how to handle non-instantiated view components with regard to this process yet. My objective here is to somehow centralize all of the bindings so that the developer can see how everything is “mapped” so to speak between view components and the data model. Technically, this is where the controller logic in the MVC pattern lies in this architecture.

Obviously there are some inherent issues that come with this.  My concern is that when an architecture has a substantial use of registries, the design patterns within the architecture become suspect.  However, it seems that it is most logical right now to use internal registries for services, commands, and events (although this may change).

Demarcation of the Business Layer

In the diagram, the demarcation of the business layer is quite clear, as I have now separated the architecture into two primary layers, one for business logic, and one for the actual GUI. For example, client-server communication and the construction of the model in the form of value objects happens within the business layer. Say for example that we have an AIR application that must ask the server if there are any tasks that have been created on the server side for it since the last time it ran. The server responds with a task to remind the user that their subscription is about to expire. That is then stored in the applications local sqllite db, and  the task is sent to a task handler queue to be handled in the background while the application is running.  When its time to handle the task, a notification event is fired, which goes through the event bus and displays the message in the UI.

Alternative Enterprise Flex Architecture - version 0.3

Alternative Enterprise Flex Architecture - version 0.3

If you have any questions and/or feedback, please do not hesitate to comment. Questions and comments are critical for identifying weaknesses with this architecture.

Possibly Related Posts:



Posted by Dan Orlando on February 12th, 2009 :: Filed under Enterprise Flex
Tags :: , ,

The “Widget-based Programming Model” for Flex Enterprise Applications

I came across this article on O’Reilly’s InsideRIA site by Moxie Zheng and was surprised to find some similarities between the architecture the author describes and the architecture that I am seeking to create. The good stuff begins under the subtitle about halfway down, labeled “The Architecture”, where Moxie Zheng discusses his use of an Event Bus the same way as I have implemented it into my own architecture.

One thing I wanted to point out, and my reason for mentioning it here, is that below that he describes what he refers to as “The Widget Programming Model”, something I have not come across before. When it comes to enterprise Flex apps, we’re usually dealing with multiple user levels. In other words, the interface must look different based on the conditions under which the user is accessing the application. These conditions are often set by an external database server that handles user management, in which user types and their respective permissions may be set in a specific table. Then each user is assigned a user type, or in some cases, multiple user types. Therefore, the client side AIR or Flex application must construct itself “on the fly” so to speak, based on the group of configuration settings that it is handed from the server side. I like this widget-based programming model because it takes custom component development to an even more loosely coupled level, making it virtually impossible for the developer to creat interdependencies within an application due to the nature under which that particular widget must be programmed. It’s loose-coupling at it’s finest.

These “widgets” are compiled as separate swf “mini-applications” if you will, encapsulating and isolating code that handles a specific way of viewing data on the server. As I wrap my brain around the possibilities with this design pattern, I can’t help but think that for applications that are powered by specialized services, a “widget registry” could in fact be formed on the network (talking about AIR applications only now). Therefore, if a user was installing the application based on a certain set of credentials, a call to the network registry would return a set of “widgets” that should be installed along with the main application, thus defining how that particular user views the application interface. This concept could easily apply to the branding of an application based on the web site it was downloaded from, as a simple example.

Possibly Related Posts:



Posted by Dan Orlando on February 2nd, 2009 :: Filed under Enterprise Flex, Tools & Innovation
Tags :: , ,