Friday, October 22, 2010

Flex Skins Demystified (for Developers)

As a developer, I can always appreciate when languages make it easy to provide a clear separation of model and view (think MVC).  In ColdFusion we utilize a framework to produce these results.  Flex also allows us to use frameworks or apply common design patterns to our code for a separation of concerns.  Flex 4 introduced a native way to separate model from view utilizing spark skins.  This is largely to improve separation of workflow between designers and developers, but for MVC nuts, it serves us well.

I've trodded through several examples online and am assembling this tutorial a as way for developers to get started utilizing skins.  There are two primary types of skinning to get started with.  The first is skinning a native Flex component.  This takes place when you want to skin an existing component such as the spark.components.Button class.

The second type of skinning is for Flex custom components.  Skinning a custom component is much the same as skinning a native Flex component.  Your custom component can extend any class that extends SkinnableComponent.  When using Spark components, this is pretty much any visual component (another great reason for you to deprecate using mx based components in your apps for their spark counterparts).  A recent example I needed to skin was a button with multiple images.  I was able to create a subclass of spark.components.Button and add my images easily, unlike the hoops Flex 3 imposed.

Spark introduced a few new base containers for our use.  spark.components.SkinnableContainer works like a Canvas, but it is a subclass of SkinnableComponent (note that Group is the spark counterpart to Canvas, but is not skinnable).  For our example we will be extending SkinnableContainer to create a custom 'mirror' component.  For kicks we are also skinning a Button. This example is easy so as not to delve to deeply at first, but should get you started to more in-depth topics like skin states.  The final product looks like this:


First, we are going to tackle the Button skin. Flash Builder's workflow for creating a skin is very straightforward.  Name your skin and pick what component (or component skin it models, and Flash Builder will copy the contents of the base skin into your new file.  To create our button skin in Flash Builder, we select New > MXML Skin.  After naming our skin we can select the host component.


The skin includes many sections, two of which we will focus on immediately:

32:  [HostComponent("spark.components.Button")]  

HostComponent tells the skin what component we are basing our skin on, and therefore gives us access to the properties of that class for use within the skin itself like style definitions.  You can technically refer to any property including data proerties, but since we are trying to separate our view layer, that seems counterintuitive ;)  The Button class itself defines SkinParts, which are a powerful way to separate all data from the design (more on SkinParts in our other example below).  For our button we want to add an image, which is very easy to do.  We could also change any SkinPart (like shadow) or state (like down or over), or even modify SkinParts only within a specific state (like what the shadow looks like when you hover over the button).

The second part we will look at is the MXML that defines the Button component view.  In a Skin we can add any markup.  Within a Skin each component has "includeIn" and "excludeFrom" attributes to determine when a component should be visible.  If the component should be visible at all times, do not use either attribute.  To add an image we use the spark.primitives.BitMapImage class:

209:  <s:BitmapImage source="@Embed('assets/nav_refresh_blue.png')" top="5" bottom="5" left="5" />  

Now that our button skin is ready to go, we need to create our ImageButton component. We are creating the ImageButton component as an MXML file in this instance, but could also create it in ActionScript (which is shown in the next example).

ImageButton.mxml
1:  <?xml version="1.0" encoding="utf-8"?>  
2:  <s:Button xmlns:fx="http://ns.adobe.com/mxml/2009"   
3:       xmlns:s="library://ns.adobe.com/flex/spark"   
4:       xmlns:mx="library://ns.adobe.com/flex/mx" skinClass="com.nictunney.skindemo.view.skins.ImageButtonSkin">  
5:  </s:Button>  
6:    

Skins are bound to components using the "skinClass" attribute.  There is absolutely nothing else to note here now, but we could add any properties or functionality in this file. Implementation of this ImageButton class will be shown at the end of this post.

For the next example we will be skinning a custom Flex component named MirrorGroup. The component doesn't do much other than display text, and then mirror the text back on the same line, reversed. To show that the component does not have to be created in MXML, this example uses all ActionScript. Our custom component extends SkinnableComponent so we can inherit the skinnable actions and parts of that base class.  The component itself is simple, with caveats:

MirrorGroup.as
1:    
2:  package com.nictunney.skindemo.view  
3:  {  
4:    import com.nictunney.skindemo.view.skins.MirrorGroupSkin;  
5:      
6:    import spark.components.Label;  
7:    import spark.components.supportClasses.SkinnableComponent;  
8:      
9:    public class MirrorGroup extends SkinnableComponent  
10:    {  
11:      [SkinPart(required="true")]  
12:      public var plainText:Label;  
13:      [SkinPart(required="true")]  
14:      public var mirrorText:Label;  
15:        
16:      public var content:String;  
17:        
18:      override public function stylesInitialized():void {  
19:        super.stylesInitialized();  
20:        this.setStyle("skinClass",Class(com.nictunney.skindemo.view.skins.MirrorGroupSkin));  
21:      }  
22:        
23:      override protected function partAdded(partName:String, instance:Object):void  
24:      {  
25:        super.partAdded(partName, instance);  
26:          
27:        if( instance == plainText || instance == mirrorText )  
28:        {  
29:          instance.text = content;  
30:        }  
31:      }  
32:        
33:    }  
34:  }  

SkinParts are really cool (lines 11-14). What they define is a contract between the designer and the developer. The developer provides a list of SkinParts to the designer as IDs, Flex component type, and if they must implement the SkinPart. The designer then creates the skin with those matching IDs and types. The SkinPart metadata tag in the MirrorGroup component tells Flex to join them up, hence linking data to view at runtime. I know this workflow was completely developer focused and backwards, but you get the idea ;)

The caveats to using an AS3 class instead of MXML that just plain sucked (until I found the right blog posts):
  1. Since we are attaching the skin in ActionScript, we must override the public stylesInitialized() method (lines 18-21).  This code comes from SEFOL.  In ImageButton.mxml this was not necessary as we specified the skinClass attribute in the component definition.
  2. We need to override the protected partAdded() method and delay processing of any properties of a SkinPart until they are added to our component from the Skin (lines 23-31).  If you do not do this you will get errors complaining about null references.  This code comes from Ryan Stewart.
The next step is to create the Skin.  Selecting New > MXML Skin in Flash Builder allows us to provide two important pieces of info:

The differences from when we created the button example are that we can specify the custom component MirrorGroup as the HostComponent, and we specify that it should create our Skin file as a copy of SkinnableContainerSkin, which is the default skin for SkinnableContainer, which we extended to create MirrorGroup.  Using the base skin gets us light years ahead.  Here is the finished Skin:

MirrorGroupSkin.mxml (stripped out boilerplate comments and ActionScript for brevity)
1:  <?xml version="1.0" encoding="utf-8"?>  
2:    
3:  <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark"   
4:    xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled="0.5">  
5:    <fx:Metadata>[HostComponent("com.nictunney.skindemo.view.MirrorGroup")]</fx:Metadata>  
6:    
7:    <s:states>  
8:      <s:State name="normal" />  
9:      <s:State name="disabled" />  
10:    </s:states>  
11:      
12:    <!--- Defines the appearance of the SkinnableContainer class's background. -->  
13:    <s:Rect id="background" left="0" right="0" top="0" bottom="0">  
14:      <s:fill>  
15:        <!--- @private -->  
16:        <s:SolidColor id="bgFill" color="#FFFFFF"/>  
17:      </s:fill>  
18:    </s:Rect>  
19:      
20:    <s:HGroup id="contentGroup" left="10" right="0" top="10" bottom="0" minWidth="0" minHeight="0">  
21:      <s:Label id="plainText" />  
22:      <s:Label id="mirrorText" layoutDirection="rtl" alpha="0.3" />  
23:    </s:HGroup>  
24:    
25:  </s:Skin>  
26:    

Line 5 shows the HostComponent has been properly referenced. The standard SkinnableContainerSkin that was copied for us comes loaded with a spark Group with a basic layout.  We have replaced this with a HGroup and two labels.  Notice all of our styling has been implemented in the skin, but our values are nowhere to be seen?  The SkinParts we defined in MirrorGroup are seen here (matching IDs are a must) as "plainText" and "mirrorText".

The final step is to create an application and use the custom components and skins.

1:    
2:  <?xml version="1.0" encoding="utf-8"?>  
3:  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
4:          xmlns:s="library://ns.adobe.com/flex/spark"   
5:          xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"  
6:          xmlns:view="com.nictunney.skindemo.view.*">  
7:      
8:    <s:VGroup top="10" left="10">  
9:      <view:ImageButton label="Toggle Mirror Visibility" click="mirrorGroup.visible = !mirrorGroup.visible" />  
10:      <view:MirrorGroup id="mirrorGroup" content="This is my text to mirror" />  
11:    </s:VGroup>  
12:      
13:  </s:Application>  
14:    

That's it! We are telling the button what to do when it is clicked (toggle visibility of the MirrorGroup). The text is also being passed into the MirrorGroup as its content property. Flex handles the rest!

Full code here

Tuesday, October 19, 2010

Using ColdFusion ORM with Flash Remoting in Flex via DTOs and Assemblers

ColdFusion 9 brought us a native implementation of Hibernate. ColdFusion has always been a wicked service tier, and extending CF ORM objects to Flex via remoting makes it even easier to connect CF and Flex.

NOTE: This information was originally explained to me over a bunch of conversations by Brian Kotek. Everything correct in this post can be attributed to Brian, and everything incorrect can be blamed on me ;).

There are a few reasons why utilizing data transfer objects (DTO) are a good idea:
  1. Reduce network overhead by only returning the data you need (BlazeDS - under the hood of remoting - has some issues with remotingfetch and lazy loading)
  2. Massage data to match the needs of the flex application's architecture (ordering arrays of children, concatenating strings, etc)
  3. Smaller footprint for serialization
A DTO is an an object that stores data. It is limited in that it knows how to do nothing else, but store data. DTOs are loaded up by an assembler (read about the dto assembler pattern). An object might have more than one assembler class depending on the method of access (such as remoting) or even the amount of data that needs loaded into an object for the present flex call. For example, one flex call might need a parent object with all related children, whereas another call might just need the parent object itself. In the latter case we could be returning a hundred objects when all we really need is a single string from the parent.

The following diagram shows a simplified workflow for reading data from a CF service tier from a Flex application:


The sample workflow shows a simple remoting call from the Flex application. The CF side receives the request in a singleton remoting proxy and uses CF ORM to load the requested object. The object is passed off to the assembler. The assembler knows how to assemble the DTO for this object. The proxy doesn't know anything about how to load the object or DTO. That functionality is injected into the proxy at runtime. When the DTO is passed back from the assembler it is returned to Flex. On the Flex side the AS3 DTO equivalent is populated and an assembler disassembles the AS3 DTO into the appropriate AS3 class.

The sample code below handles the ColdFusion side of the equation (the Flex side is the the same, but opposite). For our example we are requesting a Parent object with the specified ID via Flash Remoting. The call is received by our remoting proxy. Note that the proxy does not know how to create the Parent object or Parent DTO, but it knows where to get them via dependency injection. Take note that all of this would be even easier using if you allow ColdSpring to handle your objects ;)

RemotingProxy.cfc

1:  <cfcomponent displayname="RemotingProxy" hint="I am the RemotingProxy class.">  
2:      
3:    <!--- remote methods --->  
4:    <cffunction name="getParent" access="remote" returntype="parentDTO" output="false" displayname="getParent" hint="">    
5:      <cfargument name="parentID" type="string" required="true" />  
6:        
7:      <cfscript>  
8:        var parent = application.parentService.get(arguments.parentID);  
9:          
10:        return application.parentAssembler.assemble(parent);  
11:      </cfscript>  
12:        
13:    </cffunction>  
14:      
15:  </cfcomponent>  
The parent assembler's assemble() method takes the Parent object from ORM and maps it to the Parent DTO. The assembler then loads the children objects into the composition. It doesn't know how to assemble the ChildDTOs, but it has an instance of ChildAssembler injected into it at runtime that provides this functionality. Also note that there is a reference to the ProjectService. This is used when dissassembling. This would occur during a write operation triggered from the Flex application.

ParentAssembler.cfc

1:  component accessors="true" {  
2:    property ParentService parentService;  
3:    property ChildAssembler childAssembler;  
4:      
5:    public any function init (ParentService parentService, ChildAssembler childAssembler) {  
6:      setParentService(parentService);  
7:      setChildAssembler(childAssembler);  
8:        
9:      return this;  
10:    }  
11:      
12:    public ParentDTO function assemble (Parent parent) {  
13:      var dto = createObject('component', 'ParentDTO').init();  
14:        
15:      dto.id = parent.getID();  
16:      dto.title = parent.getTitle();  
17:        
18:      // add the children  
19:      aChildren = parent.getChildren();  
20:      for ( var i=1;i<=arrayLen(aChildren);i++ ) {  
21:        arrayAppend(dto.children, getChildAssembler().assemble(aChildren[i]));  
22:      }  
23:        
24:      return dto;  
25:    }  
26:      
27:    public Parent function disassemble (ParentDTO parentDTO) {  
28:        
29:      return ;  
30:    }  
31:  }  
The DTO stores all properties of the Parent class in public variables. You may choose to keep these variables private and provide accessors and mutators for access. The use of cfproperty here is for the purpose of self-documentation.

ParentDTO.cfc

1:  component alias="com.nictunney.dto.ParentDTO" {  
2:    
3:    property string id;  
4:    property string title;  
5:    property array children;  
6:      
7:    public any function init () {  
8:      this.id = '';  
9:      this.title = '';  
10:    
11:      this.children = [];  
12:        
13:      return this;  
14:    }  
15:  }  

The full code is available here. Hope this gets you started utilizing ColdFusion 9 ORM with your Flex applications.

Saturday, October 16, 2010

User Experience for Developers

User experience (UX) is an enigma to many developers, but is something I think developers should have a firm grasp on to excel as well as create apps that not only impress, but also work for (as well as with) the end user. Many developers do not understand the difference between UX and UI (user interface). UX defines how a user interacts with your application, whereas UI is the actual implementation of the patterns selected for the interaction. If UX is not considered in detail up front, I always expect several iterations of extra development resulting from user acceptance testing (UAT).

I had the unique opportunity to work with Will Evans and watch a master in action which really sparked my interest in user experience design. I don't have the opportunity to apply his overarching tenet that 'You are not the user' in full, I always keep it in mind when speaking with clients and while developing the UX for any app I architect.

A few important assets to understand in getting you started in UX are listed below.

User Personas
User personas were something that were uncomfortable to me at first. I was used to defining different types of users while architecting systems and agile user stories, but adding information like salary, education and age seemed uncomfortable at first. Properly defining descriptors like this help to develop usage scenarios. The user persona allows us to understand how a specific user will access the system, where they will access the system from, their technical proficiency and even if they need adaptive technology to overcome a disability. Also, being able to identify deeply with users really helps when creating stories and process flows. Performing user interviews really helps! So does observation of users performing their tasks or interacting with an existing application (if one exists).

User Stories
Much like standard application development, UX involves the creation of user stories. In software dev we generally build these stories by working with the product owner and their understanding of the system. During UX discovery it is a great idea to look beyond standard requirements and involve additional stakeholders, and EVEN MORE IMPORTANTLY: a sampling of end users. These user stories define not only a user's interactions with your application but also the process flows identified by the stories. Unlike Agile development stories, UX stories can be much more verbose, and also define personas within the context of the system.

Information Architecture (IA) and Content Inventory
For developers, this is a very familiar deliverable. Consider this a sitemap, but even more importantly, the hierarchy of how information is organized within your application. This defines how users will find information or services. IA is a huge topic in itself, and we won't be going into it in detail in this post.

Process Flows
Another familiar asset for developers, these flow diagrams are perfect for demonstrating user interactions for common system tasks. I like to create these as UML activity diagrams. Being able to walk a user or stakeholder through a workflow is very helpful and saves time in the longrun, especially considering how visual users are.

Wireframes
I'm pretty sure every developer has been in a client meeting at some point explaining some complex method of attacking a problem using a image, and the client turns to you and says, 'You know what, I think that shade of blue should be slightly darker, and perhaps the logo should be larger, and maybe we need a san-serif font here that blinks and ....'. Somehow they've entirely missed the decision they were supposed to be concentrating on and got caught up on ancillary topics. Wireframes are an awesome solution to this problem for a few reasons. Aside from just allowing you to focus on process and function over form, they are also simple to create and take much less time than full visuals. Wireframes allow you to develop experience and interaction first, managing visual design at the appropriate time once the processes have been clearly defined. Wireframes generally do not stand on their own and require annotations that call out specific details.

UX Design Patterns
I could dedicate an entire series of posts to UX patterns. Just like in software development, user experience designers have also identified common problems and sets of solutions that address said problem. By understanding the needs of your users by observation and interviews, you can apply the correct pattern (or work from a pattern) to provide a good experience. Yahoo! has a list of pattern libraries to get you started. I also highly recommend Martijn van Welie's pattern library.

Visuals
When creating high fidelity visuals (also referred to as comps) it is important to remember that you don't need to create visuals for the entire site. Generally you will have a few variations of pages that will need created. I still find lorem ipsum text important during this stage with some clients to allow to to focus on the proper items. Make sure the visuals tell enough of the story you are attempting to convey within the application flow. Many times this step is handed off to a visual designer, but ti is imperative that the UX designer remain engaged during this stage. Not always necessary, but important nonetheless, sometimes mood boards help define the artistic direction (especially when developing an entire brand experience). Mood boards can also be used to demonstrate design concepts and themes to a client before creating fully fledged visual designs.

Style Guide
A style guide is an important asset to deliver with your UX design. This allows developers to easily recreate your vision utilizing the correct hexadecimal colors and fonts. Creating a cascading style sheet is simple utilizing a style guide, and prevents developers from taking too many creative liberties with the design.

These are just a few assets to get you started. I have quite a few good examples of UX in action that I'll post depending on interest. If anyone wants additional information or examples on a single asset above, let me know and I'll wire them up.