Uses for non-visual Flex components

Brian LeGros | December 13th, 2007 | programming  

Recently, I've been interested in examining the features of non-visual components as it applies to Flex. I don't hear them talked about a lot (at least in the small part of the blog-o-sphere that I read), but I think there are some uses for these types of components that could really catch on in the community. I've tried to put together a sample application to show an example of some of the ideas I'm playing with in my head.

So the big place where I see non-visual components having a use is when attempting to bridge the stateless and stateful portions of a Flex application, mainly in the area of remote services. When I design a web service or remote object to be used by Flex, I typically build it in Java (or ColdFusion) and I design the service such that its methods operate in a stateless fashion. For example, when I call a method on my service, I don't expect previous calls to that method to influence the results of my current call; at least from the perspective of the caller. Additionally, I have the expectation that more information may be required when calling the method since the remote object receiving the call has no context in which to interpret the method call besides the method itself. Now I'm know an argument can be made about whether something truly is stateless or not, but that's not the goal of this post. Let's work with this ad hoc definition of stateless for now.

Flex provides us with a very simple, global means to get a hold of these services: RemoteObject, WebService, HttpService; there are other means by which to connect to remote services, but for now let's take the simple example of stateless RPC-based services. Typically in my Flex applications, I want to emulate a synchronous call from the application to the service (using something that implements IResponder or mapping the result/fault methods manually). Ideally I should have a class abstracting these calls to improve cohesion in the application; frameworks like to use command, delegate, or proxy classes, for example. During the emulation of this synchronous call I usually have my result/fault handler call out to a method on a class to change the state of an object (e.g. - setting values on the ModelLocator in Cairngorm), consequently firing propertyChanged events and/or custom events to update visual components via data binding.

All that being said, there are a couple of things with this approach that I want to address. First, I'm making the assumption that the class which abstracts the interactions with my service should also remain stateless. No where in the creation of the object am I changing its state so that the behaviors associated with the object may have a different context when executed. Second, I'm making the assumption that the behavior of this abstracting class must be separate from the data it uses. Propagating a change in an object's state via events is the back-bone of Flex data-binding. Not only that, but data binding is very simple to use and code, why shouldn't this simplicity be available in the ActionScript class abstracting the call to the remote service?

So that's enough conceptualizing for now, let's look at some example code. Please note the entire working example can be found at this location.

In this example, we have a very simple phone directory application. A SearchView exists which takes input from the user and announces a custom event (SearchEvent) passing that user input as its payload (i.e. - SearchCriteria). This event is handled by the Application class which in turn calls the find() method on an instance of SearchComponent. SearchComponent is a non-visual component which uses data-binding to propagate changes from the stateless world into my stateful Flex application. The code for SearchComoponent can be found below:

  1. package com.brianlegros.nvc_example.component
  2. {
  3.    import flash.xml.XMLDocument;
  4.    import mx.collections.XMLListCollection;
  5.    import mx.collections.ListCollectionView;
  6.    import mx.collections.IList;
  7.    import mx.collections.ArrayCollection;
  8.    import flash.net.URLRequest;
  9.    import flash.net.URLLoader;
  10.    
  11.    import com.brianlegros.nvc_example.vo.Employee;
  12.    import com.brianlegros.nvc_example.vo.SearchCriteria;
  13.    
  14.    public class SearchComponent
  15.    {
  16.       [Bindable]
  17.       public var locations : IList;
  18.      
  19.       [Bindable]
  20.       public var departments : IList;
  21.      
  22.       [Bindable]
  23.       public var employees : IList;
  24.      
  25.       private var data : XML;
  26.      
  27.       public function SearchComponent() : void
  28.       {
  29.          var request : URLRequest = new URLRequest("results.xml");
  30.          var loader : URLLoader = new URLLoader(request);
  31.          loader.addEventListener(Event.COMPLETE, function() : void
  32.             {
  33.                data = XML(loader.data);
  34.                
  35.                locations = findLocations();
  36.      
  37.                departments = findDepartments();
  38.             }
  39.          );
  40.          
  41.          this.employees = new ArrayCollection();
  42.       }
  43.  
  44.       private function findLocations() : ArrayCollection
  45.       {
  46.          var temp : ArrayCollection = new ArrayCollection();
  47.                  
  48.          for each(var item : XML in this.data.employee.location)
  49.          {
  50.             if(!temp.contains(item.toString()))
  51.             {
  52.                temp.addItem(item.toString());
  53.             }
  54.          }
  55.          
  56.          return temp;
  57.       }
  58.      
  59.       private function findDepartments() : ArrayCollection
  60.       {
  61.          var temp : ArrayCollection = new ArrayCollection();
  62.                  
  63.          for each(var item : XML in this.data.employee.department)
  64.          {
  65.             if(!temp.contains(item.toString()))
  66.             {
  67.                temp.addItem(item.toString());
  68.             }
  69.          }
  70.          
  71.          return temp;
  72.       }
  73.      
  74.            
  75.       public function find(criteria : SearchCriteria) : void
  76.       {       
  77.          var temp : ArrayCollection = new ArrayCollection();
  78.                  
  79.          for each(var item : XML in this.data.employee)
  80.          {
  81.             if(criteria.firstName.toUpperCase() == item.firstName.toString().toUpperCase()
  82.             || criteria.lastName.toUpperCase() == item.lastName.toString().toUpperCase()
  83.             || criteria.nickName.toUpperCase() == item.nickName.toString().toUpperCase()
  84.             || criteria.location == item.location
  85.             || criteria.department == item.department)
  86.             {
  87.                var employee : Employee = new Employee();
  88.                employee.firstName = item.firstName.toString();
  89.                employee.lastName = item.lastName.toString();
  90.                employee.nickName = item.nickName.toString();
  91.                employee.location = item.location.toString();
  92.                employee.department = item.department.toString();
  93.                employee.phone = item.phone.toString();
  94.                
  95.                temp.addItem(employee);
  96.             }
  97.          }
  98.          
  99.          this.employees = temp;
  100.       }
  101.    }
  102. }

There a few things to note about this component for the purpose of this example:

  • A method on a remote service/object is not actually being called, I'm using an XML document to simulate that process.
  • I am not actually emulating a synchronous call, I'm allowing the current thread to block on the method call. If I were to emulate the synchronous call, I would suggest using anonymous functions as the result and fault handlers for the remote service/object. The code in this example would be short and not warrant a named method mapping (this is done a lot in JavaScript when registering event handlers).
  • Yes, my coding style kinda sucks, get over it.

Now when the find() method is called it does not return anything, instead it updates the component's internal state via the employees property which then fires a propertyChanged event which is handled by ResultsView to populate a datagrid. Additionally, notice that when the object is constructed it makes a call to fetch location and department information to which controls in the SearchView are bound and updated when construction is complete. These values from these controls are used to filter the search performed by the user.

Going back to the conceptual, there are a few questions that come to mind:

  1. Aren't components supposed to be reusable? - From my POV, it feels like Flex has already done a great job of handling re-use through the RemoteObject, HttpService, and WebService classes. It seems that if re-usability is needed it would be at the service rather than the non-visual component. The non-visual component in my example is literally acting as a perspective for its service, or what potentially could be a group of services. Right now, however, I'm not sure if there are huge performance issues that may result from having multiple component perspectives for a single or series of services. I would assume for RemoteObject it may not be as big as a hit as it would be for a web service. Maybe this would be based on the remoting implementation you choose (i.e. - LCDS, BlazeDS, WebORB, Granite Data Services, etc).
  2. Aren't you just causing side-effects on objects? - In my opinion, it's not doing anything different than what Flex is doing with its visual components. In fact, what I think justifies this particular approach is the fact that you have the ability to notify anyone watching the object when its state has changed; I've always considered side effects as changes in state that I potentially didn't know about as the caller. The Flash movie instance is stateful; why not take advantage of this environment to add state to the classes abstracting our services? I'm building these non-visual components to satisfy the needs of my application, so I will know how they should behave and can to document that formally based on the constructs of the language. Now, if you ask me if this approach should be used for building an API-like interface to a set of remote services, then I would have to say no. The implementer of an API doesn't know how their code will be used in the context of an application, consequently keeping these components as stateless as possible is to the benefit of the API developer; context is limited to the execution of a method call. I think the Twitter API for Flash Developers is a great example of this.
  3. Where do I put all of these non-visual components? - This question I believe involves much more conversation about the implementation of these non-visual components. The example application is extremely simple and does not represent the issue of how to handle event propagation. In the example, all events are being propagated to the Application class and emulating a sort of global event system similar to those that I've seen in Flex frameworks with which I've worked. In fact, this is how easyMVC handles its event registration in the ControllerFactory; a ControllerEvent with a user provided type is registered on the Application and no matter where the event is dispatched, it's told to bubble to the Application to be handled by a mapped method in a custom Controller class. I have to admit that I like this approach much better than Cairngorm and PureMVC's approach of building their own global event system. I know both camps have their own reasoning for why they've done it, but I don't think that what Adobe has provided is worth re-writing. On the other hand, does the hierarchical nature of MXML bind visual component layout and construction too close such that without global event systems we can't be productive as Flex developers? On a side note, data binding in practice isn't always the answer to our problems; how a component can take advantage of these non-visual components and still interact with the components it needs to is a mystery to me. This may come back to the nature of MXML as well.
  4. Do I need a framework if I use this approach? - This is something I'm still trying to figure out. The biggest use of Flex frameworks I've found is a structured approach for making calls to remote services. I feel like frameworks have way too much boiler plate code and if this approach is practical, a good alternative may exist in place of adopting a framework. It seems to me like Flex frameworks have come from the mindset of the web world where stateless HTTP is king. We don't have to use the Front Page Controller pattern to build rich UI's; I think it's time to move on to different interpretations of the MVC pattern. I always find myself asking, did developers in the Java Swing world find themselves turning to a framework or were the constructs of Swing enough to be productive. If people were productive with Swing and it was a widget toolkit for AWT, why can't the same be true for Flex and Flash?

All this being said, this is just my latest idea. As you can tell, I still have a lot of unanswered questions. We are the process of implementing this approach on a much larger scale at work and hoping to solve the questions listed above. I'm always interested in feedback, so please rip this to shreds. I am far from experienced in this arena and am always open to what others have to say despite what some may think.

NOTE: For those who are interested, I began along this line of thinking based of the latest buzz-worthy topics in the programming community. It interested me as to how OSGI implemented their component architecture in Java w/o some language level support (e.g. - formal properties) and why it so popular. I was also intrigued by a proposal put together by Joe Noxel, from the Java Posse, regarding additions to Java for some of the language level elements already present in Flex. Additionally, SOA has come into debate by some of the more experienced professionals in software engineering and SCA (see Apache Tuscany as an example) has been identified as a potentially better alternative. So all this talk, combined with the little amount of component programming I've done with COM+ and .NET, made me wonder. If there is such a huge draw towards component-oriented design is there anything in Flex that we can do to take advantage of these practices? Does having formal properties and support for events as it presents itself in Flex aid developers with the tools necessary to utilize component-oriented design? Is one of those areas specifically the perspective of bridging the gap from the stateful component to the stateless service? Now I know a component has a much richer definition than I'm limiting it to, but this is just the point. To what extent can we, and should we, use components within Flex?

Architectual Styles - Part Four : Layering

admin | October 7th, 2007 | series  

In the fourth part of this series, I'd like to talk about my uses of layering as it applies to architectural styles. In searching for a good explanation of the Layers pattern itself, I stumbled up on this posting which I thought was a good analysis. Although the analysis is done in the context of Visual FoxPro, it gets across the mindset I have when working with the Layers pattern.

In my experience, I find myself consistently implementing layering in my applications as they grow in scale. I try to use layering as means by which to simplify the interactions between objects in my application to somewhat, well-defined levels of abstraction. I find that layering is also a good exercise in following good practices as it applies to cohesion and coupling; without an appropriate use of both, the use of layers may appear more difficult than it should be. In reading this post, please keep in mind that these abstractions are in place to help reduce complexity from the perspective of the developer. Adherence to preserving the integrity of each layer in your architecture is left up to you. In practice, you may come to find that breaking those boundaries every once and while may be more practical, but that is decision you have to come to.

So let's take a look at an overview diagram that I threw together:

Layering Overview

In the diagram there are few things that I want to point out. Firstly, I chose to show what I commonly refer to as a 3-tier layering scheme: Presentation, Business, and Integration. Semantically speaking, I've heard a lot of variations on the naming of these layers (e.g. - Presentation = Interface, Integration = Data), but for the purpose of this series let's stick with what written. Second, I've chosen to identify a few patterns in the given layers based on my previous experience with them. Please note that there are entire disciplines in software engineering devoted to pattern analysis and implementation, these are just a few that I've found useful and not a comprehensive or exclusive list. Third, for the purpose of this diagram, I've split the Presentation layer into two segments: Application and Service. Each section represents how I use the Presentation layer in the context of constructing an application with a UI or a service API. It should be assumed that the Business and Integration layers have to solve similar problems for each section, so no distinction has been made in the other layers.

With that being said, let's look at each layer in more detail:

  • Presentation - The Presentation Layer is where I place all of the classes associated with assembling some type of consumable interface for either an application or a service API.

    For an application, the typical interface I expose is a user interface. Web templates, view widgets, and other UI components make up the class types I place into this layer. Typically the Consumer for applications are end-users.

    For service APIs, I tend to expose Service classes which encompass units of work from the API as a whole, usually as methods on an object. The Service class' responsibility normally does not exceed aggregating functionality from the Business Layer. Based on the approach I'm taking, I may even include input validation as the responsibility of the Service class. Additionally, Facade/Adapter classes can be created to re-expose the functionality identified by the Service class but take only responsibility for the translation of messages to and from the consumer of the API. For example, I may not be able to call the service API by instantiating the Service class in shared memory, I may have to utilize RPC calls over SOAP. A Facade/Adapter class would be helpful for creating an interface to use as a basis for WSDL generation and translation of value objects to domain objects (more on this in a little bit). The Consumer for service APIs could be an application or another service API.

  • Business - The Business Layer is where I place all of the classes associated with the implementation of the business rules, usually as outlined by my use cases. Based on the architectural style you choose to implement (see next post in series), domain classes can potentially play a larger role in the implementations of these rules. Other classes applicable to this layer could be Validators (for business rules not input), Managers, and Unit of Work classes aggregating interactions as they relate to the Integration Layer. Although I consider the domain classes an integral portion of the "glue" between layers, I usually associate them with the Business Layer since its goals relate more directly to the problem domain than functional aspects.
  • Integration - The Integration Layer is where I place all of the classes that act as abstractions for the external resources on which my application is dependent. The responsibility of this layer usually results in classes managing connection and location information as well as domain object mapping. I typically do not find myself creating Transfer classes since most technologies (e.g. - ORM solutions) can work with my domain classes directly. In the diagram you can see some examples of the types of resources and the patterns I use to abstract them. Remember, the Integration Layer is just providing friendly abstractions; the use of those abstractions is dictated by the Business Layer. If multiple classes in the Business Layer need to send an email, both could have a common use of an EmailDelegate, for example, that exposes the basic functionality associated with sending an email. The classes in the business layer care about what's in the email, the delegate cares about how to send that email and other functional aspects of email.

Hopefully after these brief explanations, it begins to become apparent the crucial role that a domain plays in a layered architecture. The domain pervades into each layer as a contract allowing each to focus on how it can solve the problem using the behavior, or set of behaviors, for which it is responsible. This is yet another reason that semantics play such a large role in the creation of a domain; forming semantically relevant contracts between layers allow you scale your software as the solutions needed for the problem domain scale. From my experience, this turns out to not only be true as it relates to uses cases and business requirements but as it relates to functional requirements as well (e.g. - integrating something like instant messaging into the application).

That's about all I have on layering, but suffice it to say, I think migitating complexity is always a good thing when you know it will be an issue you have to address in the future. Hopefully I was able to make sense of my perspectives to help you reduce the complexities you encounter. In the next post of this series, we will get more into architectural styles as it relates to the Business Layer as I will try to convey ideas on what I consider light and heavy-weight architectures. I will also try to touch more on the idea of state and what it means for each of these styles.

Thanks for reading.

Frameworks Conference 2007 : Interface Driven Architecture

admin | May 18th, 2007 | conferences  

This talk was given by Hal Helms. Unfortunately, for the people attending the conference, Hal had his laptop confiscated by the Canadian border patrol on a trip in January. He gave a short talk about civil liberties and then went into his impressions about the current state of the programming job market and his impression of the "threat" of outsourcing. He advocated programming smarter (i.e. - education in software engineering) but acknowledged that this wasn't necessarily something which could guarantee an American edge in the battle for the job market. Hal advocated the idea of getting better via the process of architecting and managing projects from a technological perspective using Interface Driven Architectures (IDAs). This is basically the idea of fortifying some form of prototype and locking down the UI to avoid feature creep later in the development process. Hal indirectly encouraged a huge of time spent on domain modeling which was encouraging to hear.

Overall, it was good to hear any perspective on the state of our industry but the session was a little light on content.